Flask中如何让所有子路由均经过公共父路由处理?
解决Flask父Blueprint的before_request对子路由生效问题
问题根源
你当前是把rest、rest_get、rest_post作为独立Blueprint分别注册到app上,三者的URL前缀是平行关系。Flask的路由匹配会优先选择最具体的规则,所以/rest/get或/rest/post下的请求只会触发对应子Blueprint的before_request,不会自动执行父rest Blueprint的钩子。
两种可行解决方案
方案一:用Blueprint嵌套(Flask 2.0+支持)
Flask 2.0及以上版本支持Blueprint嵌套,把rest_get和rest_post注册到rest Blueprint下,而非直接注册到app,这样所有子路由的请求都会先经过父Blueprint的钩子。
修改注册代码:
# 先将子Blueprint挂载到父rest Blueprint rest.register_blueprint(rest_get, url_prefix="/get") rest.register_blueprint(rest_post, url_prefix="/post") # 再把父Blueprint注册到app app.register_blueprint(rest, url_prefix="/rest")
调整后,/rest/get/user这类请求会先执行rest的before_request,再触发rest_get的钩子,实现统一校验的需求。
方案二:抽取公共校验逻辑复用
如果你的Flask版本低于2.0,或者不想用嵌套方案,可以把公共的JWT校验抽成独立函数,在各个Blueprint的钩子中复用,或者直接添加到所有需要的Blueprint的钩子列表里。
示例代码1:直接复用函数
# 定义公共校验逻辑 @jwt_required(locations=["headers"]) def common_rest_auth(): print("************************************************* 执行公共REST校验") pass # 父rest Blueprint的钩子 @rest.before_request def rest_before(): common_rest_auth() # rest_get Blueprint的钩子 @rest_get.before_request def rest_get_before(): common_rest_auth() print("************************************ rest_get专属前置逻辑") # rest_post Blueprint同理 @rest_post.before_request def rest_post_before(): common_rest_auth() # 这里可以加rest_post特有的前置处理
示例代码2:直接添加到Blueprint的钩子列表
# 定义公共校验函数 @jwt_required(locations=["headers"]) def common_rest_before_request(): print("************************************************* 执行公共REST校验") pass # 给所有需要的Blueprint添加这个公共钩子 rest.before_request_funcs.setdefault(None, []).append(common_rest_before_request) rest_get.before_request_funcs.setdefault(None, []).append(common_rest_before_request) rest_post.before_request_funcs.setdefault(None, []).append(common_rest_before_request)
注意点
- 用嵌套Blueprint时,必须确保Flask版本≥2.0,否则会出现不支持的错误。
- 复用逻辑时,避免重复添加相同的校验规则,比如不要在父和子Blueprint中都单独加
@jwt_required,防止重复校验。
内容的提问来源于stack exchange,提问作者The Outstanding Question Asker
相关产品推荐
相关产品推荐

