登陆和生成图片验证码
Posted 天高任我飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了登陆和生成图片验证码相关的知识,希望对你有一定的参考价值。
1.生成图片 pillow
1.生成图片的模块pillow,在python中安装pillow,在Django中使用时用PIL
2. 在页面上<img id="valid-img" class="valid-img" src="/get_valid_img.png?" >
2.后端处理
1.生成一个图片对象:from PIL import Image
# 获取随机颜色的函数 def get_random_color(): return random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) def new(mode, size, color=0) 有三个参数 img_obj=Image.new( ‘RGB‘, (220,35) 图片大小 get_random_color() 返回的是元祖(255,15,22) 图片颜色 )
2.生成的图片放在磁盘或加载到内存
1.将生成的图片保存到磁盘上: with open("s10.png","wb") as f: img_obj.save(f,"png") with open("s10.png","rb") as f: data=f.read() 2.将生成的图片在内存中加载 from io import BytesIO io_obj=BytesIO() # 将生成的图片数据保存在io对象中 img_obj.save(io_obj,‘png‘) # 从io对象里面取上一步保存的数据 data=io_obj.getvalue() 3.将生成的图片返回到页面 return HttpResponse(data)
3.在图片上添加文本
from PIL import Image, ImageDraw, ImageFont draw_obj = ImageDraw.Draw(img_obj) # 生成一个图片画笔对象 # # 加载字体文件, 得到一个字体对象,路径从项目的根目录下找 font_obj = ImageFont.truetype("static/font/kumo.ttf", 28) ##生成的字符串写到图片上draw_obj.text(x,y,l,m) x为写的位置,tmp写的文本,fill文本颜色,font文本字体 draw_obj.text((20 , 0), "python", fill=(5, 55, 4), font=font_obj)
4.验证码
for i in range(6): u = chr(random.randint(65, 90)) # 生成大写字母 m = chr(random.randint(97, 122)) # 生成小写字母 l = random.randint(0, 9) tmp = random.choice([u, m, l]) tmp_list += str(tmp) print(tmp_list)
5.加干扰先和干扰点
加干扰线 width = 220 # 图片宽度(防止越界) height = 35 for i in range(5): x1 = random.randint(0, width) x2 = random.randint(0, width) y1 = random.randint(0, height) y2 = random.randint(0, height) draw_obj.line((x1, y1, x2, y2), fill=get_random_color()) # 加干扰点 for i in range(40): draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color()) x = random.randint(0, width) y = random.randint(0, height) draw_obj.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color())
6.验证码校验
1.当用户在页面上输入验证码提交后,后台要进行验证。验证码是在get_code函数中生成的 而校验实在login函数中执行的,因此需要将验证码设置为全局变量 VALID_CODE="" def get_code(): global VALID_CODE VALID_CODE =tmp_list 2.在校验时应不区分大小写: valid_code = request.POST.get("valid_code") # 获取用户填写的验证码 if valid_code.upper()==VALID_CODE.upper():pass 随机生成的验证码如何在后端保存 1. 保存在全局变量 不行 相当于所有的请求都共用一个验证码 2. 每一个请求使用一个自己生成的验证码 3.保存到session中 request.session["valid_code"]=tmp_list 校验时:验证码不能为空 if valid_code and valid_code.upper()==request.session.get("valid_code","").upper():pass
7.刷新验证码
1.原理: 在页面上打开一个图片,使用jquery操作 iEle=document.getElementById("i1) iEle.src 获得图片的网址链接 给其赋个新值:iEle.src="http://www.xxsbxn" 页面不刷新,但图片更改 2.刷新验证码:在src的值后面加上?,每次点击图片相当于更换图片链接 <img id="valid-img" class="valid-img" src="/get_valid_img.png?" alt=""> // 点击验证码图片 刷新验证码 $("#valid-img").click(function () { $(this)[0].src += "?"; })
登陆页面代码
‘‘‘ <div class="container"> <div class="row"> <form class="form-horizontal col-md-6 col-md-offset-3 login-form"> {% csrf_token %} <div class="form-group"> <label for="username" class="col-sm-2 control-label">用户名</label> <div class="col-sm-10"> <input type="text" class="form-control" id="username" name="username" placeholder="用户名"> </div> </div> <div class="form-group"> <label for="password" class="col-sm-2 control-label">密码</label> <div class="col-sm-10"> <input type="password" class="form-control" id="password" name="password" placeholder="密码"> </div> </div> <div class="form-group"> <label for="password" class="col-sm-2 control-label">验证码</label> <div class="col-sm-10"> <input type="text" name="valid_code" id="valid_code"> <img id="valid-img" class="valid-img" src="/get_valid_img.png?" alt=""> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="button" class="btn btn-default" id="login-button">登录</button> <span class="login-error"></span> </div> </div> </form> </div> </div> <script src="/static/jquery-3.3.1.js"></script> <script src="/static/bootstrap/js/bootstrap.min.js"></script> <script> $("#login-button").click(function () { // 1. 取到用户填写的用户名和密码 -> 取input框的值 var username = $("#username").val(); var password = $("#password").val(); var valid_code = $("#valid_code").val(); // 2. 用AJAX发送到服务端 $.ajax({ url: "/login/", type: "post", data: { "username": username, "password": password, "valid_code": valid_code, "csrfmiddlewaretoken": $("[name=‘csrfmiddlewaretoken‘]").val() }, success: function (data) { console.log(data); if (data.status){ // 有错误,在页面上提示 $(".login-error").text(data.msg); }else { // 登陆成功 location.href = data.msg; } } }) }); // 当input框获取焦点时将之前的错误清空 $("#username,#password").focus(function () { // 将之前的错误清空 $(".login-error").text(""); }); // 点击验证码图片 刷新验证码 $("#valid-img").click(function () { $(this)[0].src += "?"; }) </script> ‘‘‘
‘‘‘ def login(request): # if request.is_ajax(): # 如果是AJAX请求 if request.method == "POST": # 初始化一个给AJAX返回的数据 ret = {"status": 0, "msg": ""} # 从提交过来的数据中 取到用户名和密码 username = request.POST.get("username") pwd = request.POST.get("password") valid_code = request.POST.get("valid_code") # 获取用户填写的验证码 print(valid_code) print("用户输入的验证码".center(120, "=")) if valid_code and valid_code.upper() == request.session.get("valid_code", "").upper(): # 验证码正确 # 利用auth模块做用户名和密码的校验 user = auth.authenticate(username=username, password=pwd) if user: # 用户名密码正确 # 给用户做登录 auth.login(request, user) ret["msg"] = "/index/" else: # 用户名密码错误 ret["status"] = 1 ret["msg"] = "用户名或密码错误!" else: ret["status"] = 1 ret["msg"] = "验证码错误" return JsonResponse(ret) return render(request, "login.html") ‘‘‘