返回顶部

项目简要分析2

注册接口

使用单例模式重构云通信的发送短信的demo,有空看下

 

接口文档

url : /avi/v1_0/users/

请求的方式:POST

发送数据类型:json

必传的参数:mobile,sms_code,password

返回结果
类型:json
参数:errno,errmsg

获取前端的参数有

resp_dict = request.get_json()
mobile = resp_dict.get('mobile')
sms_code = resp_dict.get('sms_code')
password = resp_dict.get('password')

 检查上述数据的完整性

    if not all([mobile, sms_code, password]):
        resp = {
            'errno': RET.PARAMERR,
            'errmsg': '参数不完整'
        }
        return jsonify(resp)

 

检查手机号码的有效性

    if not re.match(r'1[34578]\d{9}', mobile):
        resp = {
            'errno': RET.DATAERR,
            'errmsg': '手机号格式错误'
        }
        return jsonify(resp)

 

业务逻辑处理

从redis中获取短信的验证码

real_sms_code = redis_store.get('sms_code_' + mobile)

 

判断验证码是否过期

 if real_sms_code is None:
        resp = {
            'errno': RET.NODATA,
            'errmsg': '短信验证码已过期'
        }
        return jsonify(resp)

 


判断用户是否输出了正确的验证码

    if real_sms_code != sms_code:
        resp = {
            'errno': RET.DATAERR,
            'errmsg': '短信验证码填写错误'
        }
        return jsonify(resp)  

 

删除验证码

redis_store.delete('sms_code_' + mobile)

 

保存用户的数据(牵扯到数据库的回滚操作)

    # 创建用户, 保存数据
    user = User(name=mobile, mobile=mobile)
    # 密码的处理, 应该交给模型类去处理.
    user.password = password

    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        # a. 记录日志
        logging.error(e)

        # b. 回滚操作
        db.session.rollback()

        # c. 返回错误数据
        resp = {
            'errno': RET.NODATA,
            'errmsg': '短信验证码已过期'
        }
        return jsonify(resp)

 

可以设置session的信息

    session['user_id'] = user.id
    session['user_name'] = mobile
    session['mobile'] = mobile

以上都正确的话注册成功

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

 

用户登陆接口

接口文档

url : /avi/v1_0/session/

请求的方式:POST

发送数据类型:json

必传的参数:mobile,password

返回结果
类型:json
参数:errno,errmsg

 

后端业务逻辑分析

 一 接受参数
   接受参数 手机号,密码

 二 参数校验
   总体的参数校验

   校验手机号的完整性

 三  获取用户的ip地址

    获取用户输入的错误次数

    判断用户输入的次数是否超过5次

    检验用户和密码是否匹配

 四 以上都正确删除,redis中用户输入错误的次数

 五 设置session 信息

 六 返回给前端结果

 分析逻辑如下:

获取前端传的参数

    resp_json = request.get_json()
    mobile = resp_json.get('mobile')
    password = resp_json.get('password')

 

检验参数的完整性

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

 

判断用户在redis中输入错误的次数,如果存在并且错误的次数超过5次,不需判断直接返回即可,在10分钟后才可以继续登录

user_ip = request.remote_addr
access_counts = redis_store.get('access_' + user_ip)
if access_counts is not None and int(access_counts) >= 5:
    return jsonify(errno=RET.REQERR, errmsg='请求已超过最大次数')

 

查询数据库判断用户的信息与密码

如果用户不存在并且输入的密码和数据库中的不一致,错误的次数+1,,返回错误的信息

user = User.query.filter_by(mobile=mobile).first()
if user is None or not user.check_password(password):

        # 累加错误次数, 并设置时间
        try:
            # incr:累加错误次数
            redis_store.incr('access_' + user_ip)
            # expire: 第一个参数 key, 第二个参数 过期时间
            redis_store.expire('access_' + user_ip, 600)
        except Exception as e:
            logging.error(e)

return jsonify(errno=RET.LOGINERR, errmsg='用户名或密码输入错误')

 

以上都完成说明用户登录的信息是正确的,用户登录成功,清除以前输入的错误次数

redis_store.delete('access_' + user_ip)

 

设置session信息,返回登录成功的信息

    session['user_id'] = user.id
    session['user_name'] = mobile
    session['mobile'] = mobile

    # 四. 返回值
    return jsonify(errno=RET.OK, errmsg='用户登录成功')

 

 

检查用户登录状态的接口

接口文档

url
/sessions
请求方式: get 
返回格式:
{
  "data": {
    "name": "18001225173"
  }, 
  "errmsg": "true", 
  "errno": "0"
}

 

尝试从session中获取用户的名字,如果存在说明用户已经登录,否则说明用户未登录

name = session.get("user_name")
    # 如果session中数据name名字存在,则表示用户已登录,否则未登录
if name is not None:
   return jsonify(errno=RET.OK, errmsg="true", data={"name": name})
else:
   return jsonify(errno=RET.SESSIONERR, errmsg="false")

 

 

判断用户是否登录的装饰器

如果用户已经登录的话,把用户的user.id保存到g变量中,g变量是随着程序的启动而生,停止而亡

def login_required(view_func):
    """检验用户的登录状态"""
    @wraps(view_func)
    def wrapper(*args, **kwargs):
        user_id = session.get("user_id")
        if user_id is not None:
            # 表示用户已经登录
            # 使用g对象保存user_id,在视图函数中可以直接使用
            # 比如后面设置头像的时候, 仍然需要获取session的数据. 为了避免多次访问redis服务器. 可以使用g变量
            g.user_id = user_id
            return view_func(*args, **kwargs)
        else:
            # 用户未登录
            resp = {
                "errno": RET.SESSIONERR,
                "errmsg": "用户未登录"
            }
            return jsonify(resp)
    return wrapper

 

 

登出接口

接口文档

url : sessions
请求的方式 : DELETE

 

清除session的数据

session.clear()
return jsonify(errno=RET.OK, errmsg="OK")

 

posted @ 2018-05-03 21:28  Crazymagic  阅读(167)  评论(0)    收藏  举报