flask---注册-验证简单逻辑api接口

把注册业务逻辑拆分三个接口:

注册的本质是在服务器上新建一个资源信息,其对应的方法是post,

而图片验证码的生成与获取,短信验证码的生成与获取是get请求。

从接口的风格来考虑拆分了三个。在一个也可以实现。

 

为什么前后端分离?
重点:提高(后端接口)代码的复用性比如任意web项目都有用户模块,如使用Django的一些试图类或视图函数内容不能用了,因为其严重依赖于模板。如前后端分离调用接口代码基本不变,大量的return直接返回给浏览器了

解耦,快速开发,责任分清,Django有MVT开发就慢了吗,前后端不分离使用?重点就是提高(后端接口)代码的复用性其他是附属功能

 

生成图片验证码

1 调用captcha扩展包,生成图片验证码,name,text,image

2 本地存储图片验证码,使用redis数据库(如发生异常,保存图片验证码失败,记录日志信息)

3 返回图片本身,设置响应的content-type(如未发生异常,则返回图片)

实现代码:

# coding=utf-8
# 导入蓝图对象
from . import api
# 导入图片验证码扩展
from ihome.utils.captcha.captcha import captcha
# 导入数据库实例
from ihome import redis_store,constants,db
# 导入flask内置的对象
from flask import current_app,jsonify,make_response,request,session
# 导入自定义的状态码
from ihome.utils.response_code import RET
# 导入模型类
from ihome.models import User
# 导入云通讯扩展包
from ihome.utils import sms


# 导入正则模块
import re
# 导入random模块,构造短信随机数
import random


@api.route('/imagecode/<image_code_id>',methods=['GET'])
def generate_image_code(image_code_id):
    # 调用captcha扩展包
    name,text,image = captcha.generate_captcha()
    # 调用redis数据库实例,存储图片验证码
    try:
        redis_store.setex('ImageCode_' + image_code_id,constants.IMAGE_CODE_REDIS_EXPIRES,text)
    except Exception as e:
        # 调用应用上下文,记录项目错误日志信息
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='保存图片验证码失败')
    # 如果未发生异常,返回图片本身
    else:
        # 使用响应对象,用来返回图片
        response = make_response(image)
        # 设置响应报文的Content-Type = 'image/jpg'
        response.headers['Content-Type'] = 'image/jpg'
        # 返回响应response
        return response

 

发送短信

获取参数–校验参数–查询数据–返回结果

 

 1. 获取参数,图片验证码和编号
 2. 校验参数的完整性,mobile(手机号),text(图片验证码),id(图片验证码id)(参数全部存在,如少,则返回参数不完整,提醒输入)
 3. 校验mobile手机号格式,使用正则(如有错误,则返回手机格式不正确)
 4. 获取本地存储的真实图片验证码
 5. 判断获取,图片验证码是否存在过期(从redis数据库不一定获取得到,try一下)
 6. 删除图片验证码(因为图片验证码只能使用一次)
 7. 比较图片验证码(判断客户输入与图片生成是否一致,可以忽略大小写)
 8. 生成短信内容,随机数(短信验证码)
 9. 查询数据库,判断手机号是否已经注册(是否查询到,try一下)
 10. 保存短信内容到redis中(生成短信验证码)
 11. 调用云通讯发送短信
 12. 保存返回结果,判断是否发送成功
 13. 返回结果
---------------------

实现代码:

@api.route('/smscode/<mobile>',methods=['GET'])
def send_sms_code(mobile):
    # 获取参数
    image_code = request.args.get('text')
    image_code_id = request.args.get('id')
    # 检查参数的完整性,any--all
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不完整')
    # 校验手机号格式是否满足
    if not re.match(r'1[3456789]\d{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号格式错误')
    # 检查图片验证码,获取本地存储的真实图片验证码
    try:
        real_image_code = redis_store.get('ImageCode_' + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询图片验证码失败')
    # 校验获取结果
    if not real_image_code:
        return jsonify(errno=RET.NODATA,errmsg='图片验证码过期')
    # 删除图片验证码,图片验证码只能操作一次
    try:
        redis_store.delete('ImageCode_' + image_code_id)
    except Exception as e:
        current_app.logger.error(e)
    # 比较图片验证码是否一致,忽略大小写
    if real_image_code.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR,errmsg='图片验证码错误')
    # 查询数据库,判断手机号是否已经注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据库异常')
    else:
        # 判断查询结果
        if user:
            return jsonify(errno=RET.DATAEXIST,errmsg='手机号已注册')
    # 构造短信随机码
    sms_code = '%06d' % random.randint(0,999999)
    # 保存短信随机码
    try:
        redis_store.setex('SMSCode_' + mobile,constants.SMS_CODE_REDIS_EXPIRES,sms_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='保存短信验证码失败')
    # 调用云通讯扩展,发送短信
    try:
        ccp = sms.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='发送短信异常')
    # 判断result是否发送成功
    # result = 0
    if 0 == result:
        return jsonify(errno=RET.OK,errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR,errmsg='发送失败')

 

注册用户

1. 获取参数,get_json()(获取请求体参数手机号短信号密码)
 2. 校验参数存在
 3. 获取详细的参数,mobile,sms_code,password
 4. 校验手机号格式
 5. 校验短信验证码
 6. 获取本地存储的真实短信验证码
 7. 判断查询结果
 8. 比较短信验证码是否正确
 9. 删除短信验证码(如果一致登入,并删除比较后的验证码)
 10. 构建模型对象,准备保存用户数据
    user = User(mobile=mobile,name=mobile)
    user.password = password
 11.使用数据库会话对象提交到数据库
 12.缓存用户信息,到redis。session['user_id']=user_id
 13.返回结果,附属信息data=user.to_dict()
--------------------- 

实现代码:

@api.route('/users',methods=['POST'])
def register():
    # 获取参数
    user_data = request.get_json()
    # 判断获取结果
    if not user_data:
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')
    # 获取详细的参数信息,mobile,sms_code,password
    # user_data['mobile']
    mobile = user_data.get('mobile')
    sms_code = user_data.get('sms_code')
    password = user_data.get('password')
    # 检查参数的完整性
    if not all([mobile,sms_code,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数缺失')
    # 手机号格式检查
    if not re.match(r'1[3456789]\d{9}',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号格式错误')
    # 判断用户是否已经注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询数据库异常')
    else:
        # 判断查询结果
        if user:
            return jsonify(errno=RET.DATAEXIST, errmsg='手机号已注册')
    # 获取本地存储的真实短信验证码
    try:
        real_sms_code = redis_store.get('SMSCode_' + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据库异常')
    # 判断查询redis的结果
    if not real_sms_code:
        return jsonify(errno=RET.NODATA,errmsg='短信验证码过期')
    # 直接比较短信验证码是否正确
    if real_sms_code != str(sms_code):
        return jsonify(errno=RET.DATAERR,errmsg='短信验证码错误')
    # 删除短信验证码
    try:
        redis_store.delete('SMSCode_' + mobile)
    except Exception as e:
        current_app.logger.error(e)
    # 准备保存用户注册信息
    user = User(mobile=mobile,name=mobile)
    # 调用模型类中的方法generate_password_hash,对密码进行加密sha256处理
    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='保存用户信息失败')
    # 缓存用户信息
    session['user_id'] = user.id
    session['mobile'] = mobile
    session['name'] = mobile
    # 返回结果
    return jsonify(errno=RET.OK,errmsg='OK',data=user.to_dict())

 

转载于:https://www.cnblogs.com/Paul-watermelon/articles/10251486.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值