Flask-JWT-Extended自定义异常处理器未生效问题排查
我的配置
我有一个Flask应用,使用Flask-JWT-Extended扩展处理用户认证,Flask-RESTx定义API。
以下是获取当前用户的路由:
@user_api.route("/", endpoint="get_user") class GetUser(Resource): """Handles HTTP requests to URL: /api/v1/user.""" @user_api.doc(security="Bearer") @user_api.response(int(HTTPStatus.OK), "Token is currently valid.", user_model) @user_api.response(int(HTTPStatus.BAD_REQUEST), "Validation error.") @user_api.response(int(HTTPStatus.UNAUTHORIZED), "Token is invalid or expired.") @user_api.marshal_with(user_model) @jwt_required() def get(self) -> User: """Validate access token and return user info.""" return current_user
在另一处,我为jwt_required()装饰器抛出的flask_jwt_extended.NoAuthorizationError异常定义了自定义错误处理器:
@jwt.unauthorized_loader def unauthorized_callback(message: str) -> ResponseReturnValue: """Get a response when a token is not present.""" response, code = default_unauthorized_callback(message) response.headers["WWW-Authenticate"] = 'Bearer realm="registered_users@mydomain.com"' return response, code
预期结果
当我发送不带授权头的GET /api/v1/user请求时,预期得到如下响应:
{ "message": "Missing Authorization Header" }
实际情况
但实际得到:
{ "message": "Internal Server Error" }
日志中出现回溯信息:
2023-08-06 17:04:28,007 [ERROR]: Exception on /api/v1/user/ [GET] Traceback (most recent call last): File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask/app.py", line 1484, in full_dispatch_request rv = self.dispatch_request() File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask/app.py", line 1469, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask_restx/api.py", line 404, in wrapper resp = resource(*args, **kwargs) File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask/views.py", line 109, in view return current_app.ensure_sync(self.dispatch_request)(**kwargs) File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask_restx/resource.py", line 46, in dispatch_request resp = meth(*args, **kwargs) File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask_restx/marshalling.py", line 244, in wrapper resp = f(*args, **kwargs) File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask_jwt_extended/view_decorators.py", line 171, in decorator verify_jwt_in_request( File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask_jwt_extended/view_decorators.py", line 98, in verify_jwt_in_request jwt_data, jwt_header, jwt_location = _decode_jwt_from_request( File "/home/kirill/programming/monet/.venv/lib/python3.10/site-packages/flask_jwt_extended/view_decorators.py", line 362, in _decode_jwt_from_request raise NoAuthorizationError(errors[0]) flask_jwt_extended.exceptions.NoAuthorizationError: Missing Authorization Header 2023-08-06 17:04:28,014 [INFO]: 127.0.0.1 - - [06/Aug/2023 17:04:28] "GET /api/v1/user/ HTTP/1.1" 500 -
异常现象
更奇怪的是,针对该行为的测试是通过的:
def test_get_user_no_header(client: FlaskClient, db: SQLAlchemy) -> None: """Test get user API request with no header provided. Checks: - Response has a valid structure. """ register_user(client) login_user(client) response = client.get(url_for("api.get_user")) assert response.status_code == HTTPStatus.UNAUTHORIZED assert "message" in response.json and response.json["message"] == "Missing Authorization Header" assert "WWW-Authenticate" in response.headers assert response.headers["WWW-Authenticate"] == WWW_AUTH_NO_TOKEN
并且当我使用--debug参数运行应用时,能返回正确响应。
但仅在常规运行应用时才会出现错误。
已尝试方案
我尝试在配置中添加TRAP_HTTP_EXCEPTIONS = True,但无效。
内容的提问来源于stack exchange,提问作者kirya_607
相关产品推荐
相关产品推荐

