Flask架构优化:如何简化接口中重复的身份校验逻辑代码
方案1:自定义权限校验装饰器(灵活适配按需启用)
该方案适合需要灵活控制哪些接口走校验的场景,仅需定义一次装饰器,后续给需要校验的接口加上装饰器即可,无需重复编写校验逻辑。
from functools import wraps from flask import g, request def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): auth_result = check_auth(request) if not auth_result.is_authorized: return unauthorized(auth_result.response) # 把校验结果存入flask全局g对象,视图函数中可以直接取用 g.auth_result = auth_result return f(*args, **kwargs) return decorated_function
改造后的接口代码示例:
@module_bp.route(f'{route_prefix}run-future/', methods=['GET']) @login_required def run_future_get() -> flask.Response: team_id = request.args.get('team_id', None) vr = external_functions.run_future_get(g.auth_result.email, team_id) return velo_response_dispatch(vr)
如果不想使用g对象,也可以在装饰器中把auth_result作为参数传入视图函数,将return行修改为return f(auth_result=auth_result, *args, **kwargs),视图函数直接接收auth_result参数即可。
方案2:蓝图before_request全局校验(适合大部分接口需校验的场景)
你当前的场景是30余个接口中仅少量不需要校验,用该方案效率更高,不需要给每个接口加装饰器,只需要给免校验的接口做标记即可。
首先先写一个标记免校验的装饰器:
def no_auth(f): f._no_auth = True return f
给蓝图注册before_request钩子:
@module_bp.before_request def check_auth_before_request(): # 判断当前接口是否标记了免校验 if getattr(module_bp.view_functions.get(request.endpoint), '_no_auth', False): return # 走统一校验逻辑 auth_result = check_auth(request) if not auth_result.is_authorized: return unauthorized(auth_result.response) # 存入g对象供视图使用 g.auth_result = auth_result
使用示例:
# 需校验的接口,不用加额外装饰器 @module_bp.route(f'{route_prefix}run-future/', methods=['GET']) def run_future_get() -> flask.Response: team_id = request.args.get('team_id', None) vr = external_functions.run_future_get(g.auth_result.email, team_id) return velo_response_dispatch(vr) # 免校验的接口,加@no_auth标记 @module_bp.route(f'{route_prefix}public/', methods=['GET']) @no_auth def public_interface(): return pre_make_response(200, '公开接口')
方案优势
- 所有校验逻辑统一维护,后续要调整未授权响应、修改校验规则,只需要修改一处代码即可,无需逐个调整接口
- 接口代码更简洁,冗余逻辑全部消除
- 两种方案都兼容你现有的校验逻辑和响应逻辑,不需要改动原有
check_auth、unauthorized等方法的实现
内容的提问来源于stack exchange,提问作者VectorVictor
相关产品推荐
相关产品推荐

