passport
在modules下创建passport包,其中创建views.py
passport下init创建蓝图
from flask import Blueprint
# 创建蓝图,并设置蓝图前缀
passport_blu = Blueprint("passport", __name__, url_prefix='/passport')
from . import views
passport下views注册蓝图路由
from flask import make_response, request, jsonify, current_app
from info import redis_store, constants
from info.utils.captcha.captcha import captcha
from info.utils.response_code import RET
from . import passport_blu
@passport_blu.route('/image_code')
def get_image_code():
"""
思路分析:
1.获取参数
2.校验参数
3.生成图片验证码
4.保存到redis
5.返回
:return:
"""
#1.获取参数
cur_id = request.args.get('cur_id')
pre_id = request.args.get('pre_id')
#2.校验参数
if not cur_id:
return jsonify(errno=RET.PARAMERR,errmsg='参数不全')
#3.生成图片验证码
try:
name,text,image_data = captcha.generate_captcha()
#4.保存到redis
#参数1:保存到redis的key
#参数2:图片验证码
#参数3:过期时间
redis_store.set('image_code:%s'%cur_id,text,constants.IMAGE_CODE_REDIS_EXPIRES)
#判断有没有上个编号
if pre_id:
redis_store.delete('image_code:%s'%pre_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR,errmsg="验证操作失败")
#5.返回图片验证码
response = make_response(image_data)
response.headers["Content-Type"] = 'image/jpg'
return response
注册蓝图到nfo下的__ init__.py中
from info.modules.passport import passport_blu
app.register_blueprint(passport_blu)
书写前台static/news/js/main.js
var imageCodeId = ""
var preimageCodeId = ""
// TODO 生成一个图片验证码的编号,并设置页面中图片验证码img标签的src属性
function generateImageCode() {
//1.生成一个随机字符串
imageCodeId = generateUUID();
//2.拼接图片url地址
image_url = '/passport/image_code?cur_id='+imageCodeId + "&pre_id="+preimageCodeId
//3.将地址设置到image标签的src属性中,为image_url
$('.get_pic_code').attr('src',image_url)
//4.记录上一次的编号
preimageCodeId = imageCodeId
}
info下创建utils包,导入captcha,和response_code.py
info下的__ init__.py添加redis.store:
手机验证码
info下创建libs包,并导入文件
注册云通讯,找到管理,将图片中的三个数据和yuntongxun下的sms.py中的数据对应的修改
如果出现提示:{'172001':'网络错误'}
解决方法:
在sms.py文件中添加如下代码
import ssl
# 取消证书验证
ssl._create_default_https_context = ssl._create_unverified_context
# 修改_serverIP的值
_serverIP = 'app.cloopen.com'
注意: 测试的短信模板编号为1
参数1: 发送给谁的手机号
参数2: ['内容', 有效时间单位分钟]
参数3: 模板编号1 【云通讯】您使用的是云通讯短信模板,您的验证码是{1},请于{2}分钟内正确输入
运行sms.py就会给对应的电话发信息
注册蓝图路由,views.py
功能描述: 发送短信
请求路径: /passport/sms_code
请求方式: POST
请求参数: mobile, image_code,image_code_id
返回值: errno, errmsg
#功能描述: 发送短信
# 请求路径: /passport/sms_code
# 请求方式: POST
# 请求参数: mobile, image_code,image_code_id
# 返回值: errno, errmsg
@passport_blu.route('/sms_code',methods=['POST'])
def get_sms_code():
"""
思路分析:
1.获取参数
2.校验参数,为空检验,格式校验
3.取出redis中的图片验证码
4.判断是否过期
5.删除redis中图片验证码
6.正确性判断
7.生成短信验证码
8.发送短信
9.判断是否发送成功
10.保存短信验证码到redis
11.返回响应
"""
# 1.获取参数
json_data = request.data
dict_data = json.loads(json_data)
mobile = dict_data.get('mobile')
image_code = dict_data.get('image_code')
image_code_id = dict_data.get('image_code_id')
# 2.校验参数,为空检验,格式校验
if not all([mobile,image_code,image_code_id]):
return jsonify(errno=RET.PARAMERR,errmsg="参数不全")
if not re.match('1[35789]\d{9}',mobile):
return jsonify(errno=RET.DATAERR,errmsg="手机号格式不正确")
# 3.取出redis中的图片验证码
try:
redis_image_code = redis_store.get('image_code:%s'%image_code_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR,errmsg="数据获取失败")
# 4.判断是否过期
if not redis_image_code:
return jsonify(errno=RET.NODATA,errmsg="图片验证码过期")
# 5.删除redis中图片验证码
try:
redis_store.delete('image_code:%s'%image_code_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR,errmsg="获取失败")
# 6.正确性判断
if image_code.upper() != redis_image_code.upper():
return jsonify(errno=RET.DATAERR,errmsg="图片验证码错误")
# # 7.生成短信验证码
sms_code = '%06d'%random.randint(0,999999)
current_app.logger.debug('短信验证码 = %s'%sms_code )
# 8.发送短信
try:
ccp = CCP()
result = ccp.send_template_sms(mobile,[sms_code,constants.SMS_CODE_REDIS_EXPIRES/60],1)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.THIRDERR,errmsg="云通讯发送失败")
# 9.判断是否发送成功
if result == -1:
return jsonify(errno=RET.DATAERR,errmsg="发送短信失败")
# 10.保存短信验证码到redis
try:
redis_store.set('sms_code:%s'%mobile,sms_code,constants.SMS_CODE_REDIS_EXPIRES)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR,errmsg="短信保存失败")
# 11.返回响应
return jsonify(errno=RET.OK,errmsg="发送成功")
书写前台static/news/js/main.js
function sendSMSCode() {
// 校验参数,保证输入框有数据填写
//移除按钮点击事件
$(".get_code").removeAttr("onclick");
var mobile = $("#register_mobile").val();
if (!mobile) {
$("#register-mobile-err").html("请填写正确的手机号!");
$("#register-mobile-err").show();
$(".get_code").attr("onclick", "sendSMSCode();");
return;
}
var imageCode = $("#imagecode").val();
if (!imageCode) {
$("#image-code-err").html("请填写验证码!");
$("#image-code-err").show();
$(".get_code").attr("onclick", "sendSMSCode();");
return;
}
// TODO 发送短信验证码
//拼接参数
var params = {
"mobile":mobile,
"image_code":imageCode,
"image_code_id":imageCodeId
}
//发送获取短信请求
$.ajax({
url:'/passport/sms_code',//请求地址
type:'post',
data:JSON.stringify(params),
contentType:'application/json',
headers:{'X-CSRFToken':getCookie('csrf_token')},
success: function (resp) {
//判断是否请求成功
if(resp.errno == '0'){
//定义倒计时时间
var num = 60;
//创建定时器
var t = setInterval(function () {
//判断是否倒计时结束
if(num == 1){
//清除定时器
clearInterval(t)
//设置标签点击事件,并设置内容
$(".get_code").attr("onclick",'sendSMSCode()');
$(".get_code").html('点击获取验证码');
}else{
//设置秒数
num -= 1;
$('.get_code').html(num + '秒');
}
},1000);//一秒走一次
}else{//发送失败
alert(resp.errmsg);
// 重新设置点击事件,更新图片验证码
$(".get_code").attr("onclick",'sendSMSCode()');
generateImageCode();
}
}
})
}
关闭CSRF