图形验证码
# 图形验证码 def get_valid_code_img(request): import random def get_random_color(): return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) from PIL import Image, ImageDraw, ImageFont img = Image.new('RGB', (270, 40), color=get_random_color()) draw = ImageDraw.Draw(img) kumo_font = ImageFont.truetype('static/Font/kumo.ttf', size=28) valid_code_str='' for i in range(5): random_num = str(random.randint(0, 9)) random_low_alpha = chr(random.randint(97, 122)) random_upper_alpha = chr(random.randint(65, 90)) random_char = random.choice([random_num, random_low_alpha, random_upper_alpha]) draw.text((i * 40 + 40, 5), random_char, fill=get_random_color(), font=kumo_font) valid_code_str += random_char # 保存验证码 request.session['valid_code_str']=valid_code_str # 添加噪点噪线 # 添加噪点噪线 width = 270 height = 40 for i in range(3): x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, height) y2 = random.randint(0, height) draw.line((x1, y1, x2, y2), fill=get_random_color()) for i in range(100): draw.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color()) # 画点 x = random.randint(0, width) y = random.randint(0, height) draw.arc((x, y, x + 2, y + 2), 0, 90, fill=get_random_color()) # 画圆 from io import BytesIO f = BytesIO() # 临时保存在内存 img.save(f, 'png') data = f.getvalue() return HttpResponse(data)
这里保存验证码一定要用session。在验证的时候,如果想通过将验证码声明为全局变量是错误的,因为当有其他用户访问服务器是会改变这个值的。
验证
from django.shortcuts import render, HttpResponse, redirect from django.contrib import auth from django.contrib.auth.models import User from django.http import JsonResponse # Create your views here. def login(request): if request.is_ajax(): user=request.POST.get('user') pwd=request.POST.get('pwd') valid_code_str = request.POST.get('valid_code_str') response={'user':None,'msg':None} if valid_code_str.upper()==request.session.get('valid_code_str').upper(): # 使输入不区分大小写 user_obj=auth.authenticate(username=user,password=pwd) # auth验证 if user_obj: auth.login(request,user_obj) # request.user对象生成 response['user']=user_obj.username else: response['msg']='用户名或密码错误' else: response['msg']='验证码错误' return JsonResponse(response) # 直接返回序列化格式数据,在前端也不需要反序列化 return render(request, 'login.html')
模板
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <form > {% csrf_token %} <div class="form-group"> <label for="">用户名</label> <input type="text" id="user" class="form-control"> </div> <div class="form-group"> <label for="">密码</label> <input type="password" id="pwd" class="form-control"> </div> <div class="row"> <div class="col-md-6"> <input type="text" class="form-control" id="valid_code"> </div> <div class="col-md-6"> <img id="valid_code_img" width="270" height="40" src="/get_valid_code_img/" alt="图形验证码"> </div> </div> <input type="button" class="btn btn-success" id="submit" value="登录"><span id="error"></span> <a href="/reg/" class="btn btn-info pull-right">注册</a> </form> </div> </div> </div> <script src="/static/jquery-3.3.1.js"></script> <script> $('#valid_code_img').click(function () { $(this)[0].src+='?'; //验证码刷新 }); $('#submit').click(function () { $.ajax({ url:'', type:'post', data:{ user:$('#user').val(), pwd:$('#pwd').val(), valid_code_str:$('#valid_code').val(), csrfmiddlewaretoken:$("[name='csrfmiddlewaretoken']").val() }, success:function (data) { if(data.user){ location.href='/index/'; //跳转页面 }else{ $('#error').text(data.msg).css({'color':'red','margin-left':'10px'});//显示错误信息 setTimeout(function(){ $('#error').text(''); //清空 },1000) //一秒后消失 } } }) ; }); </script> </body> </html>