Flask Restful 无授权错误 缺少授权头

4
我正在使用Python 3.6在生产模式下运行Flask Restful服务器,并且正在访问需要jwt身份验证的端点,但是我一直收到“ NoAuthorizationError Missing Authorization Header”错误信息。奇怪的是,使用Postman将完全相同的请求发送到我的Mac上的本地版本的Flask应用程序时,它可以正常工作而没有任何错误。问题仅出现在生产服务器上,所有pip包的版本也完全相同。 更新:我在生产服务器上使用Gunicorn,当我停止应用并使用“ python run.py”正常运行时,错误消失并返回正确的响应。 我为jwt错误设置了以下处理程序,并且在我的应用程序的本地版本中捕获了它: - jwt.token_in_blacklist_loader - jwt.expired_token_loader - jwt.invalid_token_loader - jwt.revoked_token_loader - jwt.needs_fresh_token_loader - jwt.unauthorized_loader - jwt.claims_verification_failed_loader 为了测试目的,我没有在请求本身中发送令牌。即使我这样做,错误仍然存在。 以下是我在本地Mac上的响应:
{
    "errors": {
        "application": "Missing Authorization Header",
        "validation": null
    },
    "http_status": 401,
    "message": "There was a problem authenticating your token.",
    "status": 0,
    "time": 20
}

这是实时服务器的响应:

Aug 29 17:15:15 [5168]: return self.dispatch_request(*args, **kwargs)
Aug 29 17:15:15 [5168]: File "/home/domain.com/apps/core-api/env/lib/python3.6/site-packages/flask_restful/__init__.py", line 595, in dispatch_request
Aug 29 17:15:15 [5168]: resp = meth(*args, **kwargs)
Aug 29 17:15:15 [5168]: File "/home/domain.com/apps/core-api/env/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py", line 102, in wrapper
Aug 29 17:15:15 [5168]: verify_jwt_in_request()
Aug 29 17:15:15 [5168]: File "/home/domain.com/apps/core-api/env/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py", line 31, in verify_jwt_in_request
Aug 29 17:15:15 [5168]: jwt_data = _decode_jwt_from_request(request_type='access')
Aug 29 17:15:15 [5168]: File "/home/domain.com/apps/core-api/env/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py", line 284, in _decode_jwt_from_request
Aug 29 17:15:15 [5168]: raise NoAuthorizationError(errors[0])
Aug 29 17:15:15 [5168]: flask_jwt_extended.exceptions.NoAuthorizationError: Missing Authorization Header

我一直在尝试跟踪这个问题,在这里,但是没有成功。

3个回答

9

对于其他遇到这个错误的人,实际上这是 Flask Restful 本身处理错误的问题。

方案 #1

第一个解决方法对我有效,就是传播异常... 意思是异常被重新抛出而不是由应用程序的错误处理程序处理。然而,根据这里所说,它并不是一个很好的解决方案,因为它会覆盖 Flask 的本地错误处理函数:app.handle_user_exceptionapp.handle_exception

所以你需要在你的应用程序配置中设置 PROPAGATE_EXCEPTIONS

app.config['PROPAGATE_EXCEPTIONS'] = True

解决方案 #2

我最终采用的解决方案是基于最近在此处提出的建议,增强Flask Api的错误处理程序。

from flask import Flask
from flask_restful import Api

class CustomApi(Api):
    def handle_error(self, e):
        for val in current_app.error_handler_spec.values():
            for handler in val.values():
                registered_error_handlers = list(filter(lambda x: isinstance(e, x), handler.keys()))
                if len(registered_error_handlers) > 0:
                    raise e
        return super().handle_error(e)

app = Flask(__name__)
api = CustomApi(app, prefix='/api/v2') # same params can be passed here

5

你尝试添加了吗:

"WSGIPassAuthorization On"

在您的WSGI虚拟目录配置中?默认情况下,授权头不会传递给应用程序,因为它应该由Web服务器处理。如果由Python应用程序处理,则需要在生产环境中的配置代码中使用它。 即使CORS没有问题,您也需要它,因为它将从您的请求中删除。


1
你在哪个文件中添加了? - za_ali33

2
您看到的错误意味着授权标头未传递到flask应用程序。它可能没有被发送,或者在flask无法获取它之前被某些东西剥离了。
您是否使用Apache?看起来有其他关于Apache剥离该标头的报告。也许可以查看 Apache strips down "Authorization" header(特别是‘WSGIPAssAuthorization’),看看是否能解决您的问题。

这真的很有趣。我正在使用Apache,但头文件确实存在。所以虽然你的建议对我来说不是最终解决方案,但它对于来到这个问题的人来说是一个重要的检查,并且非常相关。谢谢,它将帮助其他人。 - stwhite
哦,我觉得我误读了你的问题。你在生产配置中设置了PROPAGATE_EXCEPTIONS Flask选项吗? - vimalloc
当时我没有。不过,我刚刚发布了对我有用的答案...请在下面查看:https://dev59.com/mK7la4cB1Zd3GeqPWAZU#52102884 - stwhite
Swift还会剥离掉Authorization头信息:请参见保留的HTTP头信息:https://developer.apple.com/documentation/foundation/nsurlrequest - Joshua Wolff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接