Python Flask实现图片验证码与邮箱验证码流程详细讲解
作者:LinTa0 发布时间:2021-10-19 06:35:29
1. 图片验证码
1.1 工具类-utility.py
将所有和图片验证码有关的方法放在类 ImageCode
import random
import string
from io import BytesIO
from PIL import Image, ImageFont, ImageDraw
class ImageCode:
def rand_color(self):
"""生成用于绘制字符串的随机颜色(可以随意指定0-255之间的数字)"""
red = random.randint(32, 200)
green = random.randint(22, 255)
blue = random.randint(0, 200)
return red, green, blue
def gen_text(self):
"""生成4位随机字符串"""
# sample 用于从一个大的列表或字符串中,随机取得N个字符,来构建出一个子列表
list = random.sample(string.ascii_letters, 5)
return ''.join(list)
def draw_verify_code(self):
"""绘制验证码图片"""
code = self.gen_text()
width, height = 120, 50 # 设定图片大小,可根据实际需求调整
im = Image.new('RGB', (width, height), 'white') # 创建图片对象,并设定背景色为白色
font = ImageFont.truetype(font='arial.ttf', size=40) # 选择使用何种字体及字体大小
draw = ImageDraw.Draw(im) # 新建ImageDraw对象
# 绘制字符串
for i in range(4):
draw.text((5 + random.randint(-3, 3) + 23 * i, 5 + random.randint(-3, 3)),
text=code[i], fill=self.rand_color(), font=font)
im.show()
此时可以在上面的类中加上下面的代码,单独运行一下,看图片验证码是否会生成
ImageCode().draw_verify_code()
如果正常运行的话,会默认打开自己电脑的图片查看器,然后显示一张图片验证码
还可以在图片验证码中加上干扰线
在 类ImageCode 中,生成验证码方法 draw_verify_code() 的上面加上绘制干扰线的方法,然后在绘制时进行调用
绘制干扰线方法
def draw_lines(self, draw, num, width, height):
"""
绘制干扰线
:param draw: 图片对象
:param num: 干扰线数量
:param width: 图片的宽
:param height: 图片的高
:return:
"""
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=2)
绘制图片验证码时,在 im.show() 前调用上述绘制干扰线的方法
方法如下:
def draw_verify_code(self):
"""绘制验证码图片"""
code = self.gen_text()
width, height = 120, 50 # 设定图片大小,可根据实际需求调整
im = Image.new('RGB', (width, height), 'white') # 创建图片对象,并设定背景色为白色
font = ImageFont.truetype(font='arial.ttf', size=40) # 选择使用何种字体及字体大小
draw = ImageDraw.Draw(im) # 新建ImageDraw对象
# 绘制字符串
for i in range(4):
draw.text((5 + random.randint(-3, 3) + 23 * i, 5 + random.randint(-3, 3)),text=code[i], fill=self.rand_color(), font=font)
self.draw_lines(draw, 4, width, height) # 绘制干扰线
im.show()
然后再次运行,效果如下:
上述的图片是存储在内存里的,关闭图片后,程序会自动终止
因为最终图片是要返回到前端的,所以上述生成验证码的方法还需再次进行修改,如下:
def draw_verify_code(self):
"""绘制验证码图片"""
code = self.gen_text()
width, height = 120, 50 # 设定图片大小,可根据实际需求调整
im = Image.new('RGB', (width, height), 'white') # 创建图片对象,并设定背景色为白色
font = ImageFont.truetype(font='arial.ttf', size=40) # 选择使用何种字体及字体大小
draw = ImageDraw.Draw(im) # 新建ImageDraw对象
# 绘制字符串
for i in range(4):
draw.text((5 + random.randint(-3, 3) + 23 * i, 5 +random.randint(-3, 3)), text=code[i], fill=self.rand_color(), font=font)
self.draw_lines(draw, 4, width, height) # 绘制干扰线
# im.show() # 如需临时调试,可以直接将生成的图片显示出来
return im, code
1.2 控制层-user.py
将图片返回给前端
from flask import Blueprint, make_response, session
from common.utility import ImageCode
from module.users import Users
user = Blueprint('user', __name__)
@user.route('/vcode')
def vcode():
code, bstring = ImageCode().get_code()
response = make_response(bstring)
response.headers['Content-Type'] = 'image/jpeg'
session['vcode'] = code.lower()
return response
将上述控制器注册进程序的主入口 main.py
if __name__ == '__main__':
from controller.user import *
app.register_blueprint(user)
app.run(debug=True) # 使项目已debug方式运行
到这里,图片验证码的后端已全部实现
至于前端的话,大家在自己想要放置图片验证码的地方,加个 img 标签即可,然后 src 属性里的值为上述控制器的接口,如下:
<img src="/vcode" style="cursor:pointer;"/>
要想和网上那些点击图片验证码之后,重新生成新的图片验证码的话,就加上一个 onclick 事件
<img src="/vcode" id="loginvcode" class="col-3" style="cursor:pointer;" onclick="this.src='/vcode?'+Math.random()"/>
至于为什么后面要加一个随机数,是因为如果不加的话,前端浏览器识别到是一样的请求时,就不会重新发送,除非你强制刷新页面。但是加个随机数的话,浏览器发现每个请求都是不一样的,就会正常的发送到后端
2. 邮箱验证码
2.1 准备
此次举例使用的是QQ邮箱,使用其他邮箱也可以,操作大致一样
登录自己的QQ邮箱,开通 POP3/SMTP 服务,然后在各自的界面下找到“生成授权码”的按钮,按照各自的流程生成授权码
2.2 工具类-utility.py
在上述的工具类中新增方法
注意,最好不要将方法放在 类ImageCode,就单独放在外面就可以了,也可以新增一个邮箱类,然后放在里面
本人就直接放在外面
from smtplib import SMTP_SSL
from email.mime.text import MIMEText
from email.header import Header
def send_email(self, receiver, ecode):
"""发送邮件"""
sender = 'XXX <xxxxxxxxx@qq.com>' # 邮箱账号和发件者签名
# 定义发送邮件的内容,支持HTML和CSS样式
content = f"您的邮箱验证码为:<span style='color: red; font-size: 20px;'>{ecode}</span>"
message = MIMEText(content, 'html', 'utf-8') # 实例化邮件对象,并指定邮件的关键信息
# 指定邮件的标题,同样使用utf-8编码
message['Subject'] = Header('验证码', 'utf-8')
message['From'] = sender
message['To'] = receiver
smtpObj = SMTP_SSL('smtp.qq.com') # QQ邮件服务器的链接
smtpObj.login(user='xxxxxxxxx@qq.com', password='授权码') # 通过自己的邮箱账号和获取到的授权码登录QQ邮箱
# 指定发件人、收件人和邮件内容
smtpObj.sendmail(sender, receiver, str(message))
smtpObj.quit()
def gen_email_code(self):
str = random.sample(string.ascii_letters + string.digits, 6)
return ''.join(str)
2.3 控制层-user.py
@user.route('/ecode', methods=['POST'])
def ecode():
email = request.form.get('email')
# 对邮箱进行格式校验
if not re.match('^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$', email):
return 'email-invalid'
code = gen_email_code()
try:
send_email(email, code)
session['ecode'] = code # 将邮箱验证码保存在session中
return 'send-pass'
except:
return 'send-fail'
到这里,邮箱验证码的后端已全部实现
来源:https://blog.csdn.net/wanzijy/article/details/127159822


猜你喜欢
- 一.设置客户端网络实用工具点击“开始”-“程序”,在“Microsoft SQL Server”菜单中选择“客户端网络实用工具”。 在“别名
- 先举个例子,以前负责教育培训类网站的时候,曾经接到过这样一个项目,需求方希望做一个充满趣味性的新手入门频道,页面要炫,最好是flash,用户
- 1.panic是什么panic() 是一个内建的函数2.panic有什么用作用:可以使用panic停止程序继续运行,所以大多数都是在demo
- 用tornado web服务的基本流程1.实现处理请求的Handler,该类继承自tornado.web.RequestHandler,实现
- 本文实例展示了Python生成日历的实现方法。该实例可实现一个月的日历生成5x7的列表,列表里的没个日期为datetime类型,采用pyth
- 简述写一个简单的flask文件下载接口。依赖flask、gevent代码不废话上代码。#!/usr/bin/env python3# -*-
- JWT(JSON Web Token)是一种基于JSON的安全令牌,可以用于在不同系统之间传输认证信息。在Go中实现JWT验证,可以通过标准
- 本文实例讲述了JS页面获取 session 值,作用域和闭包。分享给大家供大家参考,具体如下:Javascript获取session的值:v
- 前言在学校太闲,就写了这个程序,可以绘制函数图像,并且可以绘制其导函数图像和不定积分的图像,效果非常不错。效果图说明1,程序无法绘制复数图像
- 本次内容主要是上周内容的延续,主要画出kitti车的行驶的轨迹同样的,我们先来看看最终实现的效果:视频接下来就进入一步步的编码环节。。。&n
- PHP有效的时间戳典型范围是格林威治时间 1901 年 12 月 13 日 20:45:54 到 203
- 开发环境说明:Python 35Pytorch 0.2CPU/GPU均可1、LSTM简介人类在进行学习时,往往不总是零开始,学习物理你会有数
- MySQL如何查看元数据锁阻塞在哪里操作步骤:1、session 1 执行: start transaction;  
- 结合这个例子分析一下结果:结合以往C语言的基础,画了一张图来解释为什么会有上面这些值的出现。先查看下Go中的这两个运算符是啥吧。①对于所有带
- 非常简单的函数,但是官网的介绍令人(令我)迷惑,所以稍加解释。 mask_select会将满足mask(掩码、遮罩等等,随便翻译)的指示,将
- 以country.xml为例,内容如下:<?xml version="1.0"?><data>
- 本文实例讲述了php从文件夹随机读取文件的方法。分享给大家供大家参考。具体实现方法如下:function RandomFile($folde
- 前言很多文章在谈及曲线平滑的时候,习惯使用拟合的概念,我认为这是不恰当的。平滑后的曲线,一定经过原始的数据点,而拟合曲线,则不一定要经过原始
- SQLite支持多种编程语言的开发调用:C, C++ , PHP, Perl, Java, C# ,Python, Ruby等。本篇先介绍P
- 在说到什么是回表查询的时候,有两个概念需要先解释清楚:分别是聚集索引(聚簇索引)和非聚集索引(非聚簇索引)聚集索引和非聚集索引MySQL规定