Flask项目图片验证码、短信验证码实现登录接口的功能

import json
import re
from flask import request, current_app, make_response, jsonify
from . import passport_blue
from ... import redis_store, constants, models, db
from ...utils.captcha.captcha import captcha
from ...utils.response_code import RET
from ...utils.send_messge.alyun_send_message import Send_SMS

# 图片验证码
@passport_blue.route('/image_code')
def image_code():
    # 1. 获取前端传递过来的参数
    cur_id = request.args.get('cur_id')
    pre_id = request.args.get('pre_id')

    # 2. 调用captcha工具获取图片验证码,验证码的值,验证码图片(二进制)
    code_name, code_text, code_image = captcha.generate_captcha()

    # 3. 将图片验证码的值保存到redis中
    try:
        # 参数1:key,参数2:value,参数3:有效期
        redis_store.set("image_code:{}".format(cur_id), code_text, constants.IMAGE_CODE_REDIS_EXPIRES)

        # 4. 判断是否有上一次的图片验证码
        if pre_id:
            redis_store.delete('image_code:{}'.format(pre_id))
    except Exception as e:
        current_app.logger.error(e)
        return '图片验证码获取失败!'
    # 返回图片
    response = make_response(code_image)
    response.headers['Content-Type'] = 'image/png'
    return response

# 短信验证码
@passport_blue.route('/sms_code', methods=['POST'])
def sms_code():
    # 1. 获取参数
    dict_data = json.loads(request.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='参数不全!')
    # 3. 校验参数,手机号码格式
    if not re.match(r'^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$', mobile):
        return jsonify(errno=RET.DATAERR, errmsg="手机号码格式错误!")

    # 4. 通过图片验证码编号获取图片验证码
    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.DATAERR, errmsg="操作redis失败!")

    # 5. 判断图片验证码是否过期
    if not redis_image_code:
        return jsonify(errno=RET.NODATA, errmsg="图片验证码已过期!")

    # 6. 判断图片验证码是否正确
    if image_code.upper() != redis_image_code.upper():
        return jsonify(errno=RET.DATAERR, errmsg="图片验证码错误!")

    # 7. 删除图片验证码
    try:
        redis_store.delete('image_code:%s' % image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg="删除图片验证码失败!")

    # 8. 生成一个随机的短信验证码并发送短信
    random_code = Send_SMS().get_random_code()  # 随机生成的code
    res_info = Send_SMS().send(mobile, random_code)
    if res_info['code'] != 'OK':
        return jsonify(errno=10000, errmsg="短信发送失败!")

    # 9. 将短信验证码存入redis中
    try:
        redis_store.set('sms_code:{}'.format(mobile), random_code, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg="短信验证码存入redis中失败!")

    # 10. 返回正确的响应
    return jsonify(errno=RET.OK, errmsg="短信发送成功!")


# 注册接口
@passport_blue.route('/register', methods=['POST'])
def register():
    # 1, 获取参数
    # data_dict = json.loads(json_data)
    data_dict = request.json  # 这一句和上面的方法是一致的,这个更简洁
    mobile = data_dict.get('mobile')
    sms_code = data_dict.get('sms_code')
    password = data_dict.get('password')
    # 2, 校验参数,为空校验
    if not all([mobile, sms_code, password]):
        return jsonify(errno=RET.DATAERR, errmsg='参数不能为空')
    # 3, 手机号作为key取出redis中的短信验证码
    try:
        redis_sms_code = redis_store.get('sms_code:{}'.format(mobile))
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='在redis中提取短信验证码失败!')
    # 4, 判断短信验证码是否过期
    if not redis_sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='短信验证码过期!')
    # 5, 判断短信验证码是否正确
    if sms_code != redis_sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误!')
    # 6, 删除短信验证码
    try:
        redis_store.delete('sms_code:{}'.format(mobile))
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='在redis中删除短信验证码失败!')
    # 7, 创建用户对象
    uer_obj = models.User()
    # 8, 设置用户对象属性
    uer_obj.nick_name = mobile
    uer_obj.mobile = mobile
    # 这里调用了User类的属性方法进行加密
    uer_obj.password = password
    uer_obj.signature = '改用户很懒,什么都没有写'
    # 9, 保存用户到数据库
    try:
        db.session.add(uer_obj)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='用户存储到数据库失败!')
    # 10, 返回响应
    return jsonify(errno=RET.OK, errmsg='注册成功!', data=uer_obj.to_dict())

你可能感兴趣的:(flask,python,后端)