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接口开发,快速便捷
来源:https://blog.csdn.net/qq_43656718/article/details/102776980