本博文源于django基础,旨在讲解如何实现非第三方库下的验证码验证。话不多说,先看效果。
实验效果
实验步骤
- 书写url
- 书写views
- 书写template
- 实验成功,收获喜悦
实验核心内容
<img src="{% url 'valid' %}"
title="点击更新验证码" id='captcha' onclick="refresh(this)" />
function refresh(obj){
$.ajax({
url: '{% url 'valid' %}',
type: 'GET',
data: {},
dataType: 'json',
timeout: 10000,
success: function(result) {
}
});
obj.src = "{% url 'valid' %}"
}
一般大家都卡在ajax,因为url吗,一个get一个设置就行了
实验细节
书写url
很关键的是,你生成的图片肯定是一个链接,因此写下这个链接地址,配合login,一并写上去。
re_path(r'^yanzhengma',views.get_valid_img,name = 'valid'),#验证码
path('login/', views.user_login, name='user_login'),
书写views
def random_img(request):
def get_random_color():
return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)
# 生成一个图片对象
img_obj = Image.new(
'RGB',
(110, 35),
get_random_color()
)
# 在生成的图片上写字符
# 生成一个图片画笔对象
draw_obj = ImageDraw.Draw(img_obj)
# 加载字体文件, 得到一个字体对象
font_obj = ImageFont.truetype("static/fonts/CALIST.TTF", 28)
# 字体文件为系统字体文件,笔者为win10系统,可在C:\Windows\Fonts中找到
# 开始生成随机字符串并且写到图片上
tmp_list = []
a = ''
for i in range(3):
u = chr(random.randint(65, 90)) # 生成大写字母
l = chr(random.randint(97, 122)) # 生成小写字母
n = str(random.randint(0, 9)) # 生成数字,注意要转换成字符串类型
tmp = random.choice([u, l, n])
tmp_list.append(tmp)
a += tmp
draw_obj.text((0 + 40 * i, 0), tmp, fill=get_random_color(), font=font_obj)
# print(a)
request.session['check_num'] = a # 将正确的验证码存至session中,以便校对
io_obj = BytesIO()
img_obj.save(io_obj, 'png')
data = io_obj.getvalue()
return data
def get_valid_img(request):
# 生成随机颜色(随机RGB值)
if request.is_ajax() or request.method=='GET':
data = random_img(request)
return HttpResponse(data,'image/png')
def user_login(request):
error = ''
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
captcha = request.POST.get('captcha')
print(captcha)
user = authenticate(username=username, password=password)
if user:
login(request, user)
if captcha == request.session['check_num']:
if request.session['login_from']:
ret = redirect(request.session['login_from'])
ret.set_cookie('is_login','1')
return ret
else:
return redirect('/index/')
else:
error='验证码有误'
else:
error = '用户或密码错误'
request.session['login_from'] = request.GET.get('url')
form = LoginForm()
return render(request, 'login.html', locals())
看起代码非常多的样子,其实分三块,
- 生成图片验证码
- ajax操作返回验证码
- login主要业务逻辑书写
千万不要慌,不要乱!!!
书写template
只把body拉过啦,其他都懂,希望对大家有所帮助
<body>
<form class="form-horizontal" action="{% url 'user_login' %}" method="post">
{% csrf_token %}
<span>user:</span>{{ form.username }}<br>
<span>password:</span>{{ form.password }}<br>
<div class="form-group">
<span>验证码:</span>
{{ form.captcha }}
<img src="{% url 'valid' %}" title="点击更新验证码" id='captcha' onclick="refresh(this)" />
</div>
<button type="reset" class="btn btn-default ">重置</button>
<button type="submit" class="btn btn-primary ">登录</button><span>{{ error }}</span>
<input type="text" id ='d3'>
</form>
</div>
<script>
function refresh(obj){
$.ajax({
url: '{% url 'valid' %}',
type: 'GET',
data: {},
dataType: 'json',
timeout: 10000,
success: function(result) {
}
});
obj.src = "{% url 'valid' %}"
}
</script>
</body>
实验总结
一个ajax动态刷新验证,我们看到的就是鼠标点点的玩意儿,背后的实现必须有条不紊,博主在实现的过程中,将ajax操作和设置值分离的时候,图片刷新就会慢一拍,改了好久才出来,希望大家看到代码不仅会明白,也会尝试去思考具体的业务逻辑。才能写出更优秀的代码!