图片验证码和短信验证码开发
图片验证码和短信验证码开发
tip :前后端分离,先开发后端,后完善前端
一、图片验证码流程
1、引入captcha包放入utils
不是独立的第三方包放入utils,独立的包放入libs里面
- captcha.py 里的生成验证码方法
captcha.generate_captcha()
- response_code.py 是各种的错误返回说明
- commons.py 是定义的正则表达转换器
from werkzeug.routing import BaseConverter# 定义正则转换器
class ReConverter(BaseConverter):""""""def __init__(self, url_map, regex):# 调用父类的初始化方法super(ReConverter, self).__init__(url_map)# 保存正则表达式self.regex = regex
2.定义验证码api路由 verify.py
GET 127.0.0.1/api/v1.0/image_codes/<image_code_id>
, 保存到redis 数据库,但是redis数据类型 redis: 字符串 列表 哈希 set
的键值对,不能用列表,[列表里只能是字符串,不能放{键值对}],哈希可以用,但是使用哈希维护有效期的时候只能整体设置,想要单条维护因此选用字符串。连接redis保存数据和设置有效期redis_store.setex("image_code_%s" % image_code_id, 180, text)
其中180s 是常量,可以放置在一个单独的constants.py
constants.py
# coding:utf-8
# 图片验证码的redis有效期, 单位:秒
IMAGE_CODE_REDIS_EXPIRES = 180
# 短信验证码的有效期
SMS_CODE_REDIS_EXPIRES = 300# 短信验证码的间隔
SEND_SMS_CODE_INYERVAL = 6
verify.py
# GET 127.0.0.1/api/v1.0/image_codes/<image_code_id>
@api.route("/image_codes/<image_code_id>")
def get_image_code(image_code_id):"""获取图片验证码: params image_code_id: 图片验证码编号:return: 正常:验证码图片 异常:返回json"""# 业务逻辑处理# 生成验证码图片# 名字,真实文本, 图片数据name, text, image_data = captcha.generate_captcha()# 将验证码真实值与编号保存到redis中, 设置有效期# redis: 字符串 列表 哈希 set# "key": xxx# 使用哈希维护有效期的时候只能整体设置# "image_codes": {"id1":"abc", "":"", "":""} 哈希 hset("image_codes", "id1", "abc") hget("image_codes", "id1")# 单条维护记录,选用字符串# "image_code_编号1": "真实值"# "image_code_编号2": "真实值"# redis_store.set("image_code_%s" % image_code_id, text)# redis_store.expire("image_code_%s" % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES)# 记录名字 有效期 记录值try:redis_store.setex("image_code_%s" % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)except Exception as e:# 记录日志current_app.logger.error(e)# return jsonify(errno=RET.DBERR, errmsg="save image code id failed")return jsonify(errno=RET.DBERR, errmsg="保存图片验证码失败")# 返回图片resp = make_response(image_data)resp.headers["Content-Type"] = "image/jpg"return resp
3.前端的完善 register.js + register.html
前端生成图片验证码的编号UUID 函数register.js
register.js
// 保存图片验证码编号
// 定义的全局变量,编号后边会使用
var imageCodeId = "";function generateUUID() {var d = new Date().getTime();if(window.performance && typeof window.performance.now === "function"){d += performance.now(); //use high-precision timer if available}var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {var r = (d + Math.random()*16)%16 | 0;d = Math.floor(d/16);return (c=='x' ? r : (r&0x3|0x8)).toString(16);});return uuid;
}
形成图片验证码的后端地址, 设置到页面中,让浏览请求验证码图片
register.js
function generateImageCode() {// 形成图片验证码的后端地址, 设置到页面中,让浏览请求验证码图片// 1. 生成图片验证码编号imageCodeId = generateUUID();// 是指图片urlvar url = "/api/v1.0/image_codes/" + imageCodeId;$(".image-code img").attr("src", url);
}
register.html 连接
<input type="text" class="form-control" name="imagecode" id="imagecode" placeholder="图片验证码" required>
<div class="input-group-addon image-code" onclick="generateImageCode();"><img src=""></div>
二、短信验证码
1、 get 请求 api/v1.0/sms_codes/
- 要先验证图片的验证码的编号和验证码是否完整,
获取参数 前端页面用户填写的图片验证码 + 前端生成 编号
校验参数 参数是否完整
从redis数据库取出真实验证码 real_image_code 网络连接有可能出现异常,抛出数据库异常
判断验证码是否过期 只要判断redis的真实的验证码是否为None - 及时删除redis的图片验证码,防止用户使用同一个图片验证码多次登陆手机号
比较验证码的值 real_image_code.lower() != image_code.lower() - 判断手机号是否发过短信验证码 设置send_flag 获取redis的标志,并在前端
.js
里定义60s 后才可以操作
判断手机号是否存在 导入db ,models, 用User.query.filter_by().first() 是否为空,is not None 手机号存在 - 随机数用格式化字符
%06d,
手机号不存在,则生成短信验证码 - 保存短信验证码+验证码的send标识 redis_store.setex() 连接数据库的要抛出异常
- 发送短信 第三方连接可能出现错误,抛出异常
- 返回值判断
# get 请求 api/v1.0/sms_codes/<mobile>
@api.route("/sms_codes/<re(r'1[34578]\d{9}'):mobile>")
def get_sms_code(mobile):# 获取参数image_code = request.args.get("image_code")image_code_id = request.args.get("image_code_id")# 校验参数if not all([image_code_id, image_code]):return jsonify(errno=RET.PARAMERR, errmsg="参数不完整")# 业务逻辑处理# 1. 从redis 取出真实验证码try:real_image_code = redis_store.get("image_code_%s" % image_code_id)except Exception as e:current_app.logger.error(e)return jsonify(errno=RET.DATAERR, errmsg="数据库异常")# 2.判断是否过期if real_image_code is None:return jsonify(errno=RET.NODATA, errmsg="验证码过期")# 删除redis 中的图片验证码 ,防止用户使用同一个图片验证码多次try :redis_store.delete("image_code_%s " % image_code_id)except Exception as e:current_app.logger.error(e)# 3. 比较验证码的值if real_image_code.lower() != image_code.lower():return jsonify(errno=RET.DATAERR, errmsg="图片验证码错误")# 手机号是否处理过,对于这个手机号的操做在60s之内是否有记录try:send_flag = redis_store.get("send_sms_code_%s " % mobile)except Exception as e:current_app.logger.error(e)else:if send_flag is not None:return jsonify(errno=RET.REQERR, errmsg="请求过于频繁,请在60 s之后再操作")# 4. 判断手机号是否存在try:user = User.query.filter_by(mobile=mobile).first()except Exception as e:current_app.logger.error(e)else:if user is not None:return jsonify(errno=RET.DATAEXIST, errmsg="手机号已存在")# 5. 随机数用格式化字符,手机号不存在,则生成短信验证码sms_code = "%06d" % random.randint(0, 999999)# ^6. 保存短信验证码try:redis_store.setex("sms_code_%s" % mobile, constants.SMS_CODE_REDIS_EXPIRES,sms_code)redis_store.setex("send_sms_code_%s" % mobile,constants.SEND_SMS_CODE_INYERVAL, 1)except Exception as e:current_app.logger.error(e)return jsonify(errno=RET.DATAERR, errmsg="保存验证码错误")# 7.发送短信try:ccp = CCP()result = ccp.send_template_sms(mobile,[sms_code,int(constants.SMS_CODE_REDIS_EXPIRES/60)],1)except Exception as e:current_app.logger.error(e)return jsonify(errno=RET.THIRDERR, errmsg="失败")#返回值print(result)if result == 0:return jsonify(errno= RET.OK, errmsg= "成功")else:return jsonify(errno= RET.THIRDERR,errmsg ="发送失败")
2、前端的完善
向后端构造请求的参数 向后端发送请求,resp 是后端返回的响应值,因为后端返回的时json字符串
//register.jsfunction sendSMSCode() {$(".phonecode-a").removeAttr("onclick");var mobile = $("#mobile").val();if (!mobile) {$("#mobile-err span").html("请填写正确的手机号!");$("#mobile-err").show();$(".phonecode-a").attr("onclick", "sendSMSCode();");return;} var imageCode = $("#imagecode").val();if (!imageCode) {$("#image-code-err span").html("请填写验证码!");$("#image-code-err").show();$(".phonecode-a").attr("onclick", "sendSMSCode();");return;}// 向后端构造请求的参数var reg_data = {image_code: imageCode ,image_code_id: imageCodeId,};// 像后端发送请求$.get("/api/v1.0/sms_codes/"+ mobile,reg_data,function(resp){//resp 是后端返回的响应值,因为后端返回的时json字符串// 所以ajax帮助我们把这个json字符串转换为js对象,resp是转换后的对象if (resp.errno =="0"){var num = 60;var timer = setInterval(function(){if (num > 1){$(".phonecode-a").html(num + "秒");num -= 1} else {$(".phonecode-a").html("获取验证码");$("..phonecode-a").attr("onclick","sendSMSCode();");clearInterval(timer)}}, 1000, 60)} else {alert(resp.errmsg);}} );}
图片验证码和短信验证码开发相关推荐
- 2020/11/03:图片验证码和短信验证码
2020/11/03:图片验证码和短信验证码 图形验证码: 流程: 看懂前端代码,理清逻辑思路,画的出流程图 settings.py配置: # 缓存配置 CACHES = {'default': {' ...
- python3中生成图片验证码和短信验证码的程序
当下,python3已经逐渐取代了python2的地位,而一些开发中常用的功能模块(如生成图片验证码和短信验证码的模块)还是基于python2封装的模块,在调用时会各种出错.因此本人稍稍整理了一套在p ...
- 图形验证码和短信验证码
图形验证码 注意事项 在虚拟环境中安装Pillow 字体文件需要在环境中测试一下(字体文件习惯放在和验证码同层目录下) import random # Image:是一个画板(context),Ima ...
- 防止刷单杜绝薅羊毛:语音验证码和短信验证码及最新一键登录(秒验点验)解决思路
1.传统的网站和APP在早期开发时很少关注到刷单防范和羊毛党问题.甚至很多网站注册没有考虑到手机绑定.在以PC为主的互联网时代网站注册时很少使用到短信验证码,随着工信部强制要求手机号必须实名认证,同时 ...
- android 验证码短信验证码,Android短信验证码倒计时验证的2种常用方式
前言 本文主要介绍的是短信验证码功能,这里总结了两种常用的方式,可以直接拿来使用. 看图 计时器 说明:这里的及时从10开始,是为了演示的时间不要等太长而修改的. 方法如下 1.第一种方式:Time ...
- java实现发送短信验证码、短信验证码防刷校验-49
一:认证服务环境搭建 1.新建gulimail-auth-server 2.整合相关依赖 <!--引入commom依赖--><dependency><groupId> ...
- api调用 python 验证码_Python短信验证码接口调用demo
基于创蓝253云通讯品台的Python短信验证码接口调用demo !/usr/local/bin/python -- coding:utf-8 -- Author: jacky Time: 14-2- ...
- 短信验证码mysql_短信验证码
public String sendCode(String phoneString){ String code=createRandomVcode();//验证码 // 用户名 String name ...
- 登录页获取短信验证码 读取短信验证码到键盘
需要实现如下效果: 首先定义一个SMSContentObserver 来拦截短信内容: package "你的包名";import android.content.Context; ...
最新文章
- import javax.servlet 出错(真的很管用)
- 获取某一日期所在月份的第一天日期或最后一天日期
- 官司在即,品胜董事长对话苹果副总裁,打脸了谁?
- Cisco路由器配置命令之模式转换命令
- NCC CAP 6.0 发布 —— 新增支持 OpenTelemetry
- javaone_JavaOne 2014:会议与合同利益冲突
- getopt和getopt_long函数
- oracle活跃用户,监控数据库中的活跃用户及其运行
- 日本媒体称东芝敲定收购富士通硬盘业务
- (43)FPGA面试技能提升篇(Questa简介)
- Android系统(111)---Android稳定性专题之开篇
- MyBatis中的一级缓存和二级缓存介绍
- 被嘲笑、误导的AI应该得到认可
- 第二阶段--个人冲刺--第七天
- 首次安装pytorch--实测可用
- android 蓝牙通讯测试工具,Android Bluetooth 学习(2)应用层实现蓝牙设备查找、tcp_ip通信...
- 8B10B编码表,8B10B编码表格,8B10B查表内容
- js网页特效动画(筋斗云案例)
- cdn连接失败是什么意思_CDN经常连接失败的原因有哪些?
- OneTab下载,chrome插件,crx下载