flask项目1实战:2、用户注册(待完善)

在这里插入图片描述

(根据居然老师直播课内容整理)

一 、csrf验证

二、图形验证码

详见:flask项目1实战:2.2 flask框架下使用图片验证码

三、短信验证码

详见:[flask项目1实战:2.3 flask框架下使用图片验证码]

四、用户注册

1、用户注册业务逻辑分析

在这里插入图片描述

2、设计用户注册接口基本思路

  • 对于接口的设计,我们要根据具体的业务逻辑,设计出适合业务逻辑的接口。
  • 设计接口的思路:

2.1 分析要实现的业务逻辑:

  • 明确在这个业务中涉及到几个相关子业务。
  • 将每个子业务当做一个接口来设计。

2.2 分析接口的功能任务,明确接口的访问方式与返回数据:

  • 请求方法(如GET、POST、PUT、DELETE等)。
  • 请求地址。
  • 请求参数(如路径参数、查询字符串、表单、JSON等)。
  • 响应数据(如HTML、JSON等)。

3、用户注册接口设计(待梳理)

3.1请求方式

选项 方案
请求方法 POST
请求地址 /users

3.2 请求参数:表单参数

参数名 类型 是否必传 说明
password string 密码
password2 string 确认密码
mobile string 手机号
sms_code string 短信验证码

3.3 响应结果

响应结果 响应内容
注册失败 响应错误提示
注册成功 重定向到首页

4、用户注册接口定义

  • 接收参数
  • 验证参数
    • 必传参数是否为空
    • 手机号是否符合规: r’1[345678]\d{9}’ ,防止恶意注册
    • 两次密码是否一致
  • 业务逻辑验证
    • 验证短信验证码正确性:图形验证码就不再验证(图形验证码正确后,才会有短信验证码)
      • 从redis取短信验证码进行验证
      • 判断短信验证码是否过期
      • 从redis中删除短信验证码:不管对错,都只能使用一次,防止撞库
      • 判断用户填写的短信验证是否正确
    • 检查手机号是否注册过:发送短信验证码时已验证过,可以不验证,(如果该字段不是unique,建议还是验证一下,因本次该段是unique,添加数据时,如果重复会报错,故此处可不验证,在保存数据时捕获异常)
      • 查询手机号是否存在,如果有记录表示注册过,提示,否则可以注册
      • 如果查询数据库错误,直接返回异常
    • 密码加密:
      • 对密码明文进行加密:调用密码加密算法
  • 将注册信息写入数据库
    • 通过数据模型保存数据,注意数据提交和异常后的数据回滚
  • 保存登录状态到session中
  • 返回结果
@api.route("/users",methods=["POST"])
def register():
    """
        注册
        :param: 手机号 短信验证码  密码 确认密码
        :return: json
        """
    # 接收参数
    request_dict = request.get_json()
    mobile = request_dict.get("mobile")
    sms_code = request_dict.get("sms_code")
    password = request_dict.get("password")
    password2 = request_dict.get("password2")

    # 验证
    if not all([mobile, sms_code, password, password2]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不完整')

    # 判断手机号格式
    if not re.match(r'1[345678]\d{9}', mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号格式错误')
        
    # 判断两次密码是否一致
    if password != password2:
        return jsonify(errno=RET.PARAMERR, errmsg='两次密码不一致')
        
    # 业务逻辑
    # 从redis取短信验证码
    try:
        real_sms_code = redis_store.get("sms_code_%s" % mobile)
    except Exception as e:
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='读取短信验证码异常')

    # 判断短信验证码是否过期
    if real_sms_code is None:
        return jsonify(errno=RET.NODATA, errmsg='短信验证码失效')

    # 删除redis中的短信验证码
    try:
        redis_store.delete("sms_code_%s" % mobile)
    except Exception as e:
        logging.error(e)

    # 判断用户填写的验证码的正确性
    real_sms_code=real_sms_code.decode()
    if sms_code.lower()!=real_sms_code:
        return jsonify(errno=RET.DATAERR, errmsg='短信验证码错误')

    # 判断手机号是否存在
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        logging.error(e)
    else:
        if user is not None:
            # 表示手机号已经被注册过
            return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经存在')

    # 保存数据(同时检测手机是否被注册过)
    user = User(name=mobile, mobile=mobile)
    user.passwd_hash(password)
    try:
        db.session.add(user)
        db.session.commit()
    except IntegrityError as e:
        db.session.rollback()
        logging.error(e)
        return jsonify(errno=RET.DATAEXIST, errmsg='手机号已经存在')
    except Exception as e:
        # 回滚
        db.session.rollback()
        logging.error(e)
        return jsonify(errno=RET.DBERR, errmsg='插入数据库异常')
        
    # 保存登录状态到session中
    session["name"] = mobile
    session["mobile"] = mobile
    session["user_id"] = user.id

    return jsonify(errno=RET.OK, errmsg='注册成功')

五、用户注册优化

  • 采用生产者消费者开发模式优化发送短信等待

猜你喜欢

转载自blog.csdn.net/laoluobo76/article/details/110242511
今日推荐