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函数中的默认参数
Mar 30 Python
用Python的Django框架完成视频处理任务的教程
Apr 02 Python
Python3实现简单可学习的手写体识别(实例讲解)
Oct 21 Python
Python中矩阵库Numpy基本操作详解
Nov 21 Python
python语音识别实践之百度语音API
Aug 30 Python
使用Python OpenCV为CNN增加图像样本的实现
Jun 10 Python
Python获取数据库数据并保存在excel表格中的方法
Jun 12 Python
Laravel框架表单验证格式化输出的方法
Sep 25 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
Oct 14 Python
Python测试Kafka集群(pykafka)实例
Dec 23 Python
Python3 Click模块的使用方法详解
Feb 12 Python
Python HTMLTestRunner如何下载生成报告
Sep 04 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 利用Mail_MimeDecode类提取邮件信息示例
2014/01/26 PHP
PHP简单选择排序算法实例
2015/01/26 PHP
php文件读取方法实例分析
2015/06/20 PHP
微信公众号开发之通过接口删除菜单
2017/02/20 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
js调用flash的效果代码
2008/04/26 Javascript
鼠标滑上去后图片放大浮出效果的js代码
2011/05/28 Javascript
jQuery 无刷新分页实例代码
2013/11/12 Javascript
jquery实现通用版鼠标经过淡入淡出效果
2014/06/15 Javascript
JavaScript中的对象序列化介绍
2014/12/30 Javascript
jQuery实现冻结表头的方法
2015/03/09 Javascript
一个php+js实时显示时间问题
2015/10/12 Javascript
Bootstrap每天必学之弹出框(Popover)插件
2016/04/25 Javascript
如何理解jQuery中的ajaxSubmit方法
2017/03/13 Javascript
JavaScript 实现 Tab 点击切换实例代码
2017/03/25 Javascript
JS全角与半角转化实例(分享)
2017/07/04 Javascript
JS SetInterval 代码实现页面轮询
2017/08/11 Javascript
浅谈如何通过node.js对数据进行MD5加密
2018/05/16 Javascript
JavaScript中Array方法你该知道的正确打开方法
2018/09/11 Javascript
vue中v-for循环给标签属性赋值的方法
2018/10/18 Javascript
javascript简单实现深浅拷贝过程详解
2019/10/08 Javascript
python插入排序算法的实现代码
2013/11/21 Python
pygame 精灵的行走及二段跳的实现方法(必看篇)
2017/07/10 Python
Python错误处理操作示例
2018/07/18 Python
python Dijkstra算法实现最短路径问题的方法
2019/09/19 Python
python实现获取单向链表倒数第k个结点的值示例
2019/10/24 Python
Python使用sqlite3模块内置数据库
2020/05/07 Python
matplotlib对象拾取事件处理的实现
2021/01/14 Python
Web前端绘制0.5像素的几种方法
2017/08/11 HTML / CSS
CSS3图片旋转特效(360/60/-360度)
2013/10/10 HTML / CSS
Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)
2020/03/18 HTML / CSS
设计师大码女装:11 Honoré
2020/05/03 全球购物
基层干部2014全国两会学习心得体会
2014/03/10 职场文书
离职证明范本(5篇)
2014/09/19 职场文书
2016年五四青年节校园广播稿
2015/12/17 职场文书
在CSS中映射鼠标位置并实现通过鼠标移动控制页面元素效果(实例代码)
2021/04/22 HTML / CSS