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 相关文章推荐
简单的编程0基础下Python入门指引
Apr 01 Python
详解Python中的多线程编程
Apr 09 Python
Python读写Json涉及到中文的处理方法
Sep 12 Python
NumPy 如何生成多维数组的方法
Feb 05 Python
Python Grid使用和布局详解
Jun 30 Python
Flask框架Flask-Principal基本用法实例分析
Jul 23 Python
python版本单链表实现代码
Sep 28 Python
python实现统计文本中单词出现的频率详解
May 20 Python
在Python中合并字典模块ChainMap的隐藏坑【推荐】
Jun 27 Python
django 微信网页授权认证api的步骤详解
Jul 30 Python
利用python Selenium实现自动登陆京东签到领金币功能
Oct 31 Python
Python基于gevent实现文件字符串查找器
Aug 11 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
php中通过curl smtp发送邮件
2012/06/05 PHP
自己在做项目过程中学到的PHP知识收集
2012/08/20 PHP
php实现XSS安全过滤的方法
2015/07/29 PHP
PHP实现的ID混淆算法类与用法示例
2018/08/10 PHP
巧妙破除网页右键禁用的十大绝招
2006/08/12 Javascript
JQuery插件Style定制化方法的分析与比较
2012/05/03 Javascript
Extjs4 关于Store的一些操作(加载/回调/添加)
2013/04/18 Javascript
JavaScript显示当然日期和时间即年月日星期和时间
2013/10/29 Javascript
jquery ajax jsonp跨域调用实例代码
2013/12/11 Javascript
js判断字符长度以及中英文数字等
2013/12/31 Javascript
JavaScript控制按钮可用或不可用的方法
2015/04/03 Javascript
js仿黑客帝国字母掉落效果代码分享
2020/11/08 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
2016/08/02 Javascript
AngularJS教程之MVC体系结构详解
2016/08/16 Javascript
全面解析标签页的切换方式
2016/08/21 Javascript
jQuery UI制作选项卡(tabs)
2016/12/13 Javascript
js获取地址栏参数的两种方法
2017/06/27 Javascript
详解redis在nodejs中的应用
2018/05/02 NodeJs
微信小程序开发问题之wx.previewImage
2018/12/25 Javascript
2019 年编写现代 JavaScript 代码的5个小技巧(小结)
2019/01/15 Javascript
详解关于微信setData回调函数中的坑
2019/02/18 Javascript
微信小程序搭建自己的Https服务器
2019/05/02 Javascript
通过vue手动封装on、emit、off的代码详解
2019/05/29 Javascript
浅谈layer弹出层按钮颜色修改方法
2019/09/11 Javascript
js代码实现轮播图
2020/05/04 Javascript
VueCli生产环境打包部署跨域失败的解决
2020/11/13 Javascript
Python help()函数用法详解
2014/03/11 Python
浅析Python的web.py框架中url的设定方法
2016/07/11 Python
python实现图片处理和特征提取详解
2017/11/13 Python
python深度优先搜索和广度优先搜索
2018/02/07 Python
Python面向对象之继承原理与用法案例分析
2019/12/31 Python
欧迪办公美国官网:Office Depot
2016/08/22 全球购物
优秀中专生推荐信
2013/11/17 职场文书
业绩倒数第一的检讨书
2014/09/24 职场文书
详解MindSpore自定义模型损失函数
2021/06/30 Python
python+pytest接口自动化之token关联登录的实现
2022/04/06 Python