flask实现验证码并验证功能


Posted in Python onDecember 05, 2019

什么是Flask?

Flask是一个用Python编写的Web应用程序框架,Flask是python的web框架,最大的特征是轻便,让开发者自由灵活的兼容要开发的feature。 它由 Armin Ronacher 开发,他领导一个名为Pocco的国际Python爱好者团队。 Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。两者都是Pocco项目。

效果图:

点击图片、刷新页面、输入错误点击登录时都刷新验证码

flask实现验证码并验证功能

实现步骤:

第一步:先定义获取验证码的接口

verificationCode.py

#验证码
@api.route('/imgCode')
def imgCode():
  return imageCode().getImgCode()

此处的@api是在app下注册的蓝图,专门用来做后台接口,所以注册了api蓝图

flask实现验证码并验证功能

第二步:实现接口逻辑

1)首先实现验证码肯定要随机生成,所以我们需要用到random库,本次需要随机生成字母和数字,

所以我们还需要用到string。string的ascii_letters是生成所有字母 digits是生成所有数字0-9。具体代码如下

def geneText():
  '''生成4位验证码'''
  return ''.join(random.sample(string.ascii_letters + string.digits, 4)) #ascii_letters是生成所有字母 digits是生成所有数字0-9

2)为了美观,我们需要给每个随机字符设置不同的颜色。我们这里用一个随机数来给字符设置颜色

def rndColor():
  '''随机颜色'''
  return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))

3)此时我们已经可以生产图片验证码了,利用上面的随机数字和随机颜色生成一个验证码图片。

这里我们需要用到PIL库,此时注意,python3安装这个库的时候不是pip install PIL 而是pip install pillow。

def getVerifyCode():
  '''生成验证码图形'''
  code = geneText()
  # 图片大小120×50
  width, height = 120, 50
  # 新图片对象
  im = Image.new('RGB', (width, height), 'white')
  # 字体
  font = ImageFont.truetype('app/static/arial.ttf', 40)
  # draw对象
  draw = ImageDraw.Draw(im)
  # 绘制字符串
  for item in range(4):
    draw.text((5 + random.randint(-3, 3) + 23 * item, 5 + random.randint(-3, 3)),
         text=code[item], fill=rndColor(), font=font)
  return im, code

4)此时,验证码图片已经生成。然后需要做的就是把图片发送到前端去展示。

def getImgCode():
  image, code = getVerifyCode()
  # 图片以二进制形式写入
  buf = BytesIO()
  image.save(buf, 'jpeg')
  buf_str = buf.getvalue()
  # 把buf_str作为response返回前端,并设置首部字段
  response = make_response(buf_str)
  response.headers['Content-Type'] = 'image/gif'
  # 将验证码字符串储存在session中
  session['imageCode'] = code
  return response

这里我们采用讲图片转换成二进制的形式,讲图片传送到前端,并且在这个返回值的头部,需要标明这是一个图片。

将验证码字符串储存在session中,是为了一会在登录的时候,进行验证码验证。

5)OK,此时我们的接口逻辑已经基本完成。然后我们还可以给图片增加以下干扰元素,比如增加一点横线。

def drawLines(draw, num, width, height):
  '''划线'''
  for num in range(num):
    x1 = random.randint(0, width / 2)
    y1 = random.randint(0, height / 2)
    x2 = random.randint(0, width)
    y2 = random.randint(height / 2, height)
    draw.line(((x1, y1), (x2, y2)), fill='black', width=1)

然后getVerifyCode函数需要新增一步

def getVerifyCode():
  '''生成验证码图形'''
  code = geneText()
  # 图片大小120×50
  width, height = 120, 50
  # 新图片对象
  im = Image.new('RGB', (width, height), 'white')
  # 字体
  font = ImageFont.truetype('app/static/arial.ttf', 40)
  # draw对象
  draw = ImageDraw.Draw(im)
  # 绘制字符串
  for item in range(4):
    draw.text((5 + random.randint(-3, 3) + 23 * item, 5 + random.randint(-3, 3)),
         text=code[item], fill=rndColor(), font=font)
  # 划线
  drawLines(draw, 2, width, height)
  return im, code

最终接口逻辑完成。整体接口代码如下

from .. import *
from io import BytesIO
import random
import string
from PIL import Image, ImageFont, ImageDraw, ImageFilter
#验证码
@api.route('/imgCode')
def imgCode():
  return imageCode().getImgCode()
class imageCode():
  '''
  验证码处理
  '''
  def rndColor(self):
    '''随机颜色'''
    return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
  def geneText(self):
    '''生成4位验证码'''
    return ''.join(random.sample(string.ascii_letters + string.digits, 4)) #ascii_letters是生成所有字母 digits是生成所有数字0-9
  def drawLines(self, draw, num, width, height):
    '''划线'''
    for num in range(num):
      x1 = random.randint(0, width / 2)
      y1 = random.randint(0, height / 2)
      x2 = random.randint(0, width)
      y2 = random.randint(height / 2, height)
      draw.line(((x1, y1), (x2, y2)), fill='black', width=1)
  def getVerifyCode(self):
    '''生成验证码图形'''
    code = self.geneText()
    # 图片大小120×50
    width, height = 120, 50
    # 新图片对象
    im = Image.new('RGB', (width, height), 'white')
    # 字体
    font = ImageFont.truetype('app/static/arial.ttf', 40)
    # draw对象
    draw = ImageDraw.Draw(im)
    # 绘制字符串
    for item in range(4):
      draw.text((5 + random.randint(-3, 3) + 23 * item, 5 + random.randint(-3, 3)),
           text=code[item], fill=self.rndColor(), font=font)
    # 划线
    self.drawLines(draw, 2, width, height)
    return im, code
  def getImgCode(self):
    image, code = self.getVerifyCode()
    # 图片以二进制形式写入
    buf = BytesIO()
    image.save(buf, 'jpeg')
    buf_str = buf.getvalue()
    # 把buf_str作为response返回前端,并设置首部字段
    response = make_response(buf_str)
    response.headers['Content-Type'] = 'image/gif'
    # 将验证码字符串储存在session中
    session['imageCode'] = code
    return response

第三步:前端展示。

这里前端我使用的是layui框架。其他框架类似。

<div class="layui-form-item">
  <label class="layui-icon layui-icon-vercode" for="captcha"></label>
  <input type="text" name="captcha" lay-verify="required|captcha" placeholder="图形验证码" autocomplete="off"
      class="layui-input verification captcha" value="">
  <div class="captcha-img">
    <img id="verify_code" class="verify_code" src="/api/imgCode" onclick="this.src='/api/imgCode?'+ Math.random()">
  </div>
</div>

js:主要是针对验证失败以后,刷新图片验证码

// 进行登录操作
      form.on('submit(login)', function (data) {
        console.log(data.elem);
        var form_data = data.field;
        //加密成md5
        form_data.password=$.md5(form_data.password);
        $.ajax({
          url: "{{ url_for('api.api_login') }}",
          data: form_data,
          dataType: 'json',
          type: 'post',
          success: function (data) {
            if (data['code'] == 0) {
              location.href = "{{ url_for('home.homes') }}";
            } else {
              //登录失败则刷新图片验证码
              var tagImg = document.getElementById('verify_code');
              tagImg.src='/api/imgCode?'+ Math.random();
              console.log(data['msg']);
              layer.msg(data['msg']);
            }
          }
        });
        return false;
      });

第四步:验证码验证

验证码验证需要在点击登录按钮以后,在对验证码进行效验

1)首先我们获取到前端传过来的验证码。.lower()是为了忽略大小写

这里的具体写法为什么这样写可以获取到前端传过来的参数,可以自行了解flask框架

if request.method == 'POST':
  username = request.form.get('username')
  password = request.form.get('password')
  captcha = request.form.get('captcha').lower()

2)对验证码进行验证.因为我们在生成验证码的时候,就已经把验证码保存到session中,这里直接取当时生成的验证码,然后跟前端传过来的值对比即可。

if captcha==session['imageCode'].lower():
   pass
 else:
   return jsonify({'code':-1,'msg':'图片验证码错误'})

到此,已完成了获取验证码、显示验证码、验证验证码的所有流程。验证验证码中没有把整体代码写出来。可以根据自己情况自己写。

总结

以上所述是小编给大家介绍的flask实现验证码并验证功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
Python下载懒人图库JavaScript特效
May 28 Python
python 采集中文乱码问题的完美解决方法
Sep 27 Python
python实现折半查找和归并排序算法
Apr 14 Python
详解如何在python中读写和存储matlab的数据文件(*.mat)
Feb 24 Python
Python Selenium Cookie 绕过验证码实现登录示例代码
Apr 10 Python
python实现屏保计时器的示例代码
Aug 08 Python
对python文件读写的缓冲行为详解
Feb 13 Python
python实现趣味图片字符化
Apr 30 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
Aug 09 Python
手把手教你进行Python虚拟环境配置教程
Feb 03 Python
Pyinstaller加密打包应用的示例代码
Jun 11 Python
python 用递归实现通用爬虫解析器
Apr 16 Python
使用python写一个自动浏览文章的脚本实例
Dec 05 #Python
Python字节单位转换实例
Dec 05 #Python
使用Python paramiko模块利用多线程实现ssh并发执行操作
Dec 05 #Python
Python使用指定字符长度切分数据示例
Dec 05 #Python
python从zip中删除指定后缀文件(推荐)
Dec 05 #Python
python3 求约数的实例
Dec 05 #Python
python生成特定分布数的实例
Dec 05 #Python
You might like
thinkphp数据查询和遍历数组实例
2014/11/28 PHP
php正则提取html图片(img)src地址与任意属性的方法
2017/02/08 PHP
laravel学习笔记之模型事件的几种用法示例
2017/08/15 PHP
Javascript中的window.event.keyCode使用介绍
2011/04/26 Javascript
JavaScript中的property和attribute介绍
2011/12/26 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
2012/08/14 Javascript
在jQuery中 常用的选择器介绍
2013/04/16 Javascript
Javascript中的call()方法介绍
2015/03/15 Javascript
AngularJS快速入门
2015/04/02 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
2015/08/07 Javascript
轻松学习jQuery插件EasyUI EasyUI实现树形网络基本操作(2)
2015/11/30 Javascript
JS实现图片平面旋转的方法
2016/03/01 Javascript
JS实现快速的导航下拉菜单动画效果附源码下载
2016/11/01 Javascript
认识less和webstrom的less配置方法
2017/08/02 Javascript
jQuery UI Draggable + Sortable 结合使用(实例讲解)
2017/09/07 jQuery
js计算两个时间差 天 时 分 秒 毫秒的代码
2019/05/21 Javascript
详解Vue项目引入CreateJS的方法(亲测可用)
2019/05/30 Javascript
[39:08]完美世界DOTA2联赛PWL S3 LBZS vs CPG 第一场 12.12
2020/12/16 DOTA
Python正则表达式非贪婪、多行匹配功能示例
2017/08/08 Python
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
Python使用Tkinter实现机器人走迷宫
2018/01/22 Python
Python3爬虫之urllib携带cookie爬取网页的方法
2018/12/28 Python
详解python中的hashlib模块的使用
2019/04/22 Python
Python数据类型之Set集合实例详解
2019/05/07 Python
浅谈python多进程共享变量Value的使用tips
2019/07/16 Python
python类中super() 的使用解析
2019/12/19 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
canvas实现扭蛋机动画效果的示例代码
2018/10/17 HTML / CSS
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
世界闻名的衬衫制造商:Savile Row Company
2018/07/30 全球购物
努力学习演讲稿
2014/05/10 职场文书
2015年银行工作总结范文
2015/04/01 职场文书
2015年优质护理服务工作总结
2015/04/08 职场文书
2015年电信员工工作总结
2015/05/26 职场文书
2016年大学生实习单位评语
2015/12/01 职场文书
Windows11 Insider Preview Build 25206今日发布 更新内容汇总
2022/09/23 数码科技