图片验证码和短信验证码开发

tip :前后端分离,先开发后端,后完善前端

一、图片验证码流程

1、引入captcha包放入utils

不是独立的第三方包放入utils,独立的包放入libs里面

  1. captcha.py 里的生成验证码方法captcha.generate_captcha()
  2. response_code.py 是各种的错误返回说明
  3. 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);}} );}

图片验证码和短信验证码开发相关推荐

  1. 2020/11/03:图片验证码和短信验证码

    2020/11/03:图片验证码和短信验证码 图形验证码: 流程: 看懂前端代码,理清逻辑思路,画的出流程图 settings.py配置: # 缓存配置 CACHES = {'default': {' ...

  2. python3中生成图片验证码和短信验证码的程序

    当下,python3已经逐渐取代了python2的地位,而一些开发中常用的功能模块(如生成图片验证码和短信验证码的模块)还是基于python2封装的模块,在调用时会各种出错.因此本人稍稍整理了一套在p ...

  3. 图形验证码和短信验证码

    图形验证码 注意事项 在虚拟环境中安装Pillow 字体文件需要在环境中测试一下(字体文件习惯放在和验证码同层目录下) import random # Image:是一个画板(context),Ima ...

  4. 防止刷单杜绝薅羊毛:语音验证码和短信验证码及最新一键登录(秒验点验)解决思路

    1.传统的网站和APP在早期开发时很少关注到刷单防范和羊毛党问题.甚至很多网站注册没有考虑到手机绑定.在以PC为主的互联网时代网站注册时很少使用到短信验证码,随着工信部强制要求手机号必须实名认证,同时 ...

  5. android 验证码短信验证码,Android​短信验证码倒计时验证的2种常用方式

    前言 ​本文主要介绍的是短信验证码功能,这里总结了两种常用的方式,可以直接拿来使用. 看图 计时器 说明:这里的及时从10开始,是为了演示的时间不要等太长而修改的. 方法如下 1.第一种方式:Time ...

  6. java实现发送短信验证码、短信验证码防刷校验-49

    一:认证服务环境搭建 1.新建gulimail-auth-server 2.整合相关依赖 <!--引入commom依赖--><dependency><groupId> ...

  7. api调用 python 验证码_Python短信验证码接口调用demo

    基于创蓝253云通讯品台的Python短信验证码接口调用demo !/usr/local/bin/python -- coding:utf-8 -- Author: jacky Time: 14-2- ...

  8. 短信验证码mysql_短信验证码

    public String sendCode(String phoneString){ String code=createRandomVcode();//验证码 // 用户名 String name ...

  9. 登录页获取短信验证码 读取短信验证码到键盘

    需要实现如下效果: 首先定义一个SMSContentObserver 来拦截短信内容: package "你的包名";import android.content.Context; ...

最新文章

  1. import javax.servlet 出错(真的很管用)
  2. 获取某一日期所在月份的第一天日期或最后一天日期
  3. 官司在即,品胜董事长对话苹果副总裁,打脸了谁?
  4. Cisco路由器配置命令之模式转换命令
  5. NCC CAP 6.0 发布 —— 新增支持 OpenTelemetry
  6. javaone_JavaOne 2014:会议与合同利益冲突
  7. getopt和getopt_long函数
  8. oracle活跃用户,监控数据库中的活跃用户及其运行
  9. 日本媒体称东芝敲定收购富士通硬盘业务
  10. (43)FPGA面试技能提升篇(Questa简介)
  11. Android系统(111)---Android稳定性专题之开篇
  12. MyBatis中的一级缓存和二级缓存介绍
  13. 被嘲笑、误导的AI应该得到认可
  14. 第二阶段--个人冲刺--第七天
  15. 首次安装pytorch--实测可用
  16. android 蓝牙通讯测试工具,Android Bluetooth 学习(2)应用层实现蓝牙设备查找、tcp_ip通信...
  17. 8B10B编码表,8B10B编码表格,8B10B查表内容
  18. js网页特效动画(筋斗云案例)
  19. cdn连接失败是什么意思_CDN经常连接失败的原因有哪些?
  20. OneTab下载,chrome插件,crx下载

热门文章

  1. android-历史版本
  2. jQurey中getJSON方法错误回调方法
  3. 【官方】BootCDN-稳定、快速、免费的前端开源项目 CDN 加速服务
  4. 数据流图详解(DFD)
  5. 如何挑选视频会议摄像头?
  6. unittest使用详解
  7. KVM虚拟化部署Centos
  8. 数电和计算机网络,数电计算机网络试卷2010A.doc
  9. 共享栈的简单实现(C语言)
  10. 《计算机系统基础》—— 运算