flask @login_required重构

flask 自带登录视图函数login_required,在前后端不分离情况下,我们可以直接调用官方的,但现在大部分项目都是前后端分离,以接口的形式出现,还有sign验证签名,下面是鄙人小改@login_required 实现登录视图验证和sign验证

源码:

(代码不多,短小精悍,源码用到LoginManager模块这里不做详述)

def login_required(func):
	@wraps(func)
    def decorated_view(*args, **kwargs):
        if request.method in EXEMPT_METHODS:
            return func(*args, **kwargs)
        elif current_app.login_manager._login_disabled:
            return func(*args, **kwargs)
        elif not current_user.is_authenticated:
            return current_app.login_manager.unauthorized()
        return func(*args, **kwargs)
    return decorated_view

在源码基础上进行修饰(其中make_response()在下面)

参数解析请参考官方文档

def login_required(func):
	@wraps(func)
    def decorated_view(*args, **kwargs):
    
    	# 参数解析部分 其中make_response()为自己封装的函数  见下面代码块
    	# 具体加密算法和sign验证请参考贵公司方式,这里不做详细解释
		headers_parsers = reqparse.RequestParser()
        headers_parsers.add_argument('x-auth-announce', type=str, required=True, location='headers')
        headers_parsers.add_argument('x-auth-channel', choices=['WEB', "IOS", "ANDROID"], required=True, location='headers')
        headers_parsers.add_argument('x-auth-timestamp', type=str, required=True, location='headers')
        headers_parsers.add_argument('x-auth-token', type=str, required=True, location='headers')
        headers_parsers.add_argument('x-auth-version', type=str, required=True, location='headers')
        headers_parsers.add_argument('x-auth-signature', type=str, required=True, location='headers')
        head_parser = headers_parsers.parse_args()
        announce = head_parser.get('x-auth-announce')
        channel = head_parser.get('x-auth-channel')
        timestamp = head_parser.get('x-auth-timestamp')
        token = head_parser.get('x-auth-token')
        version = head_parser.get('x-auth-version')
        receive_sign = head_parser.get('x-auth-signature')

        # 验证时间戳  5分钟内可访问
        time_end = int(time.time()) + 5
        time_start = time_end - 305
        if len(timestamp) != 13:
            return make_response(code=401, msg='timestamp: Unconfirmed account:3')
        try:
            timestamp1 = int(timestamp[:-3])
        except:
            return make_response(code=401, msg='timestamp: Unconfirmed account:2')

        if not (time_start <= timestamp1 <= time_end):
            return make_response(code=401, msg='Unconfirmed account:1')

        my_sign = get_sign(announce, channel, timestamp, token, version)

        my_sign = my_sign.decode('utf-8')

        # 验证加密 sign值
        if receive_sign != my_sign:
            return make_response(code=401, msg='Unconfirmed account:0')
		# 此处为自己封装的redis链接函数(验证token)
        redis = RedisConnection()
        if not redis.get(token):
            return current_app.login_manager.unauthorized()
        return func(*args, **kwargs)
    return decorated_view

make_response() 定制接口返回函数

def make_response(code=200, msg='success', data=None, data_name='data', page_size=None, page_num=None, count=None):
    if code == 200:
        if data is None:
            response = jsonify({"code": code, "msg": msg})
        elif data and page_num and count:
            response = jsonify({"code": code, "msg": msg,
                                "data": {data_name: data, 'page_size': page_size, 'page_num': page_num,
                                         'count': count}})
        elif data and page_num and not count:
            response = jsonify(
                {"code": code, "msg": msg, "data": {data_name: data, 'page_size': page_size, 'page_num': page_num}})
        elif data and not page_num and count:
            response = jsonify({"code": code, "msg": msg, "data": {data_name: data, 'count': count}})
        else:
            response = jsonify({"code": code, "msg": msg, "data": data})
    else:
        response = jsonify({"code": code, "msg": msg})
        response.status_code = code
    return response

接下来就可以像原来一样使用@login_required用于api接口开发,快速便捷

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