Flask蓝图集成Flask-JWT-Extended时,注册jwt.user_lookup_loader后调用current_user仍报错的问题排查
解决Flask-JWT-Extended current_user报错:缺少@jwt.user_lookup_loader回调
这个问题我之前也踩过坑,核心原因是JWTManager的初始化时机和蓝图里的回调注册时机搞反了,导致你的@jwt.user_lookup_loader装饰的函数没有被正确绑定到Flask应用上。
为什么会出现这个问题?
看你的create_app函数:你先调用了jwt.init_app(app)完成JWTManager的初始化,之后才在app.app_context()里导入蓝图。这就意味着,蓝图里的@jwt.user_lookup_loader装饰器是在JWT已经和应用绑定之后才注册的,Flask-JWT-Extended没办法把这个回调关联到已初始化的应用实例上,自然就会报错说找不到回调。
至于@jwt.user_identity_loader看起来正常,大概率是因为你生成令牌的逻辑在同一个蓝图里,而令牌生成时的回调检查没有那么严格,但实际上这个回调也可能存在潜在问题。
解决方案:调整初始化和导入顺序
把蓝图的导入移到jwt.init_app(app)之前,这样蓝图里的装饰器会先注册到全局的jwt实例上,之后再初始化JWTManager时,这些回调就会被正确绑定到应用上。
修改后的create_app代码:
jwt = JWTManager() def create_app(): app = Flask(__name__, instance_relative_config=False) app.config.from_mapping(JWT_SECRET_KEY=os.environ["JWT_SECRET_KEY"]) ... # 先导入蓝图,触发装饰器注册到jwt实例 from . import login_bp # 再初始化JWTManager,此时回调已经注册完毕 jwt.init_app(app) ... app.register_blueprint(login_bp.bp)
额外的规范建议
虽然不是当前错误的直接原因,但Flask装饰器的顺序最好遵循规范:路由装饰器@bp.route应该放在最靠近函数的位置,其他功能装饰器(比如@jwt_required)放在它上面。调整后的logout路由:
@bp.route("/logout", methods=['POST']) @jwt_required() def logout(): rpc.cache_service.forget_user(current_user.id) return {"status": "OK"}
验证回调是否注册成功
你可以在create_app里加一行打印,确认回调是否被正确注册:
jwt.init_app(app) print(jwt._user_lookup_callback) # 如果输出不是None,说明注册成功
内容的提问来源于stack exchange,提问作者Michail Highkhan
相关产品推荐
相关产品推荐

