文章目录
登录.注册模块
注册
不同的功能会创建不同的蓝图模块,注册这块我们创建的是passport模块,当然都是在module目录里创建如图:
蓝图创建好了记得在app中注册
目录分析
第三方平台(云通讯)的使用
第三方随机生成验证码
图片验证码
注册好后我们先分析后台发送图片验证码的步骤
后端
import re
import random
import datetime
from info import sr, db
from . import passport_blue
from info import constants
from info.models import User
from info.response_code import RET
from flask import request, abort, jsonify, current_app, make_response,session
from info.utils.captcha.captcha import captcha
from info.libs.yuntongxun.sms import CCP
@passport_blue.route("/imageCodeId", methods=["get"])
def passpost():
"""
发送图片验证码
1.接收参数(imageCodeId)
2.校验参数是否为空
3.使用第三方辅助文件 生成图片验证码
4.将验证码保存到redis
5.返回图片验证码
:return:
"""
# 1.
# 接收参数(imageCodeId)
imageCodeId = request.args.get("imageCodeId")
# 2.
# 校验参数是否为空
if not imageCodeId:
abort(403)
# 3.
# 生成图片验证码
img_name, img_captcha, img = captcha.generate_captcha()
# 4.
# 将验证码保存到redis,并设置有效时长
sr.set("ImgCode:" + imageCodeId, img_captcha)
print(img_captcha)
# 5.
# 返回图片验证码
res_img = make_response(img)
res_img.headers["Content-Type"] = "img/jpg"
return res_img
前端js
生成uuid:
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;
}
代码:
var imageCodeId = ""
// TODO 生成一个图片验证码的编号,并设置页面中图片验证码img标签的src属性
function generateImageCode() {
imageCodeId=generateUUID()
var url= "/passport/imageCodeId?imageCodeId="+imageCodeId
$(".get_pic_code").attr("src",url)
}
注意
短信验证码
发送短信验证码js
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;
}
var params = {
'mobile':mobile,
'image_code':imageCode,
'image_code_id':imageCodeId
};
// TODO 发送短信验证码
$.ajax({
url:'/passport/sms_code', // 请求地址
type:'post', // 请求方法
data:JSON.stringify(params),// 请求参数
contentType:'application/json',// 数据类型
success:function (response) { // 回调函数
if (response.errno == '0') {
// 发送短信验证码成功
alert(response.errmsg);
} else {
alert(response.errmsg);
}
}
});
}
接口
后端
步骤:
1.获得参数(image_code', mobile, image_code_id, )图片验证码,手机号, 密钥
2.校验参数
2.1 所有参数不能为空
2.2 手机号是否正确
2.3 图片验证码是否正确
3.使用 random 生成随机短信验证码
4.将验证码保存到redis数据库
5.使用第三方平台发送短信
6.返回结果
@passport_blue.route("/sms_code", methods=["get", "POST"])
def sms_code():
"""
1.获得参数(image_code', mobile, image_code_id, )图片验证码,手机号, 密钥
2.校验参数
2.1 所有参数不能为空
2.2 手机号是否正确
2.3 校验图片验证码是否正确
3.使用 random 生成随机短信验证码
4.将验证码保存到redis数据库
5.使用第三方平台发送短信
6.返回结果
:return:
"""
# 1.
# 获得参数(image_code', mobile, image_code_id, )图片验证码,手机号, 密钥
imageCode = request.json.get("image_code")
mobile = request.json.get("mobile")
image_code_id = request.json.get("image_code_id")
# 2.1
# 校验参数不能为空
if not all([imageCode, mobile, image_code_id]):
return jsonify(errno=RET.NODATA, errmsg="参数缺少")
# 2.2 校验手机号是否正确
if not re.findall("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])[0-9]{8}$", mobile):
return jsonify(errno=RET.DATAERR, errmsg="参数错误")
# 2.3
# 校验图片验证码是否正确
server_img_code = sr.get("ImgCode:" + image_code_id)
if not server_img_code.strip().lower() == imageCode.strip().lower():
return jsonify(errno=RET.DATAERR, errmsg="参数错误")
# 3.
# 使用 random 生成随机短信验证码
random_sms = "%04d" % random.randint(0, 9999)
print(random_sms)
# 4.
# 将验证码保存到redis数据库
try:
sr.set("SMS_Code:" + mobile, random_sms,ex=constants.IMAGE_CODE_REDIS_EXPIRES)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="数据库保存错误")
# 5.
# 发送短信\
ccp = CCP().send_template_sms(mobile, [random_sms, constants.IMAGE_CODE_REDIS_EXPIRES / 60], 1)
if ccp != 0:
return jsonify(errno=RET.DATAERR, errmsg="参数错误")
# 6.
# 返回结果
return jsonify(errno=RET.OK, errmsg="发送短信成功")
注册
注册按钮 js:
代码:
// TODO 注册按钮点击
$(".register_form_con").submit(function (e) {
// 阻止默认提交操作
e.preventDefault()
// 取到用户输入的内容
var mobile = $("#register_mobile").val()
var smscode = $("#smscode").val()
var password = $("#register_password").val()
if (!mobile) {
$("#register-mobile-err").show();
return;
}
if (!smscode) {
$("#register-sms-code-err").show();
return;
}
if (!password) {
$("#register-password-err").html("请填写密码!");
$("#register-password-err").show();
return;
}
if (password.length < 6) {
$("#register-password-err").html("密码长度不能少于6位");
$("#register-password-err").show();
return;
}
// 发起注册请求
var params = {
'mobile':mobile,
'smscode':smscode,
'password':password
};
$.ajax({
url:'/passport/register', // 请求地址
type:'post', // 请求方法
data:JSON.stringify(params), // 请求参数
contentType:'application/json',
headers:{'X-CSRFToken':getCookie('csrf_token')}, // 在请求头中带上csrf_token
success:function (response) {
if (response.errno == '0') {
// 注册成功
location.reload();
} else {
alert(response.errmsg);
}
}
});
})
})
接口
后端
步骤
1 接收参数 ( mobile,smscode,password)
2 校验参数
2.1 参数是否为空
2.2 手机号是否正确
2.3 redis存储的短信验证码是为空
2.4 短信验证码是否一样
3 写入用户表
4 保持状态
5.返回结果
@passport_blue.route("/register", methods=["POST"])
def register():
"""
1 接收参数 ( mobile,smscode,password)
2 校验参数
2.1 参数是否为空
2.2 手机号是否正确
2.3 redis存储的短信验证码是为空
2.4 短信验证码是否一样
3 写入用户表
4 保持状态
5.返回结果
:return:
"""
# 1
# 接收参数(mobile, smscode, password)
mobile = request.json.get("mobile")
smscode = request.json.get("smscode")
password = request.json.get("password")
# 2
# 校验参数
# 2.1
# 参数是否为空
if not all([mobile, smscode, password]):
return jsonify(errno=RET.PARAMERR, errmsg="参数缺少")
# 2.2
# 手机号是否正确
if not re.findall("^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])[0-9]{8}$", mobile):
return jsonify(errno=RET.DATAERR, errmsg="参数错误")
# 2.3
# redis存储的短信验证码是为空
try:
server_smscode=sr.get("SMS_Code:" + mobile)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="验证码已失效")
# 2.4
# 短信验证码是否一样
if not server_smscode == smscode.strip():
return jsonify(errno=RET.DATAERR,errmsg="短信验证码不一致")
# 3
# 写入用户表
user=User()
user.nick_name=mobile
user.mobile=mobile
user.last_login=datetime.datetime.now()
user.password=password
try:
db.session.add(user)
db.session.commit()
except Exception as e:
current_app.logger.error(e)
db.session.rollback()
return jsonify(errno=RET.DBERR, errmsg="注册失败")
# 4
# 保持状态
session["user_id"]=user.id
session["user_mobile"] = user.mobile
session["user_nick_name"] = user.nick_name
# 5.
# 返回结果
return jsonify(errno=RET.OK,errmsg="注册成功")
登录
注册后我们都有保持登录在session写值
在首页渲染的时候获得session判断是否有值,没值右上角出现登录/注册,有值展示个人信息
后端:
在index渲染之前做处理所以在index模块
步骤:
@index_blue.route("/")
def index():
"""
首页
1.右上登录处理
1.1 获得session
1.2 用session在数据库中查找
1.3 返回结果
:return:
"""
# 获得session
user_id=session.get("user_id")
# 用session在数据库中查找
user=None
try:
user = User.query.filter_by(id=user_id).first()
except Exception as e:
current_app.logger.error(e)
abort(404)
content={
"user":user
}
# 返回结果
return render_template("news/index.html",content=content)
前端逻辑展示:
退出登录:
将session的值删掉在重新渲染首页
@passport_blue.route("/logout", methods=["get", "POST"])
def logout():
"""
退出登录
1.删除session
2.返回结果
:return:
"""
# 1.
# 删除session
session.pop("user_id",None)
session.pop("user_mobile", None)
session.pop("user_nick_name", None)
# 2.
# 返回结果
return jsonify(errno=RET.OK,errmsg="退出成功")
退出js
function logout() {
// $.ajax({
// url:'/passport/logout',
// type:'get'
// });
$.get('/passport/logout', function (response) {
if (response.errno == '0') {
// 退出登录成功
location.reload();
} else {
alert(response.errmsg);
}
})
}