Flask Restful NoAuthorizationError 缺少授权标头

Posted

技术标签:

【中文标题】Flask Restful NoAuthorizationError 缺少授权标头【英文标题】:Flask Restful NoAuthorizationError Missing Authorization Header 【发布时间】:2019-02-04 20:24:57 【问题描述】:

我正在使用 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

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

【问题讨论】:

【参考方案1】:

您看到的错误意味着授权标头没有弥补到烧瓶应用程序。要么它没有被发送,要么在烧瓶到达之前有什么东西把它剥离了。

您使用的是 Apache 吗?似乎还有其他关于 Apache 剥离该标头的报告。或许可以查看Apache strips down "Authorization" header(特别是“WSGIPAssAuthorization”),看看是否可以为您解决问题。

【讨论】:

这真的很有趣。我正在使用 apache,但标题存在。因此,虽然您的建议对我来说不是最终解决方案,但对于提出这个问题的人来说,这是一项重要的检查,而且非常相关。谢谢,它会帮助别人。 哦,我想我看错了你的问题。您是否在生产配置中设置了 PROPAGATE_EXCEPTIONS 烧瓶设置? 当时我没有。但是,我刚刚发布了对我有用的答案...在下面查看:***.com/a/52102884/415763 Swift 还去除了 Authorization 标头:请参阅 Reserverd HTTP 标头:developer.apple.com/documentation/foundation/nsurlrequest【参考方案2】:

对于遇到此错误的其他人来说,这实际上是 Flask Restful 本身以及它如何处理错误的问题。

解决方案 #1

第一个对我有用的解决方案是propagate the exceptions...,这意味着异常会重新引发,而不是由应用程序的错误处理程序处理。但是,according to this 这不是一个很好的解决方案,因为它覆盖了 Flask 的原生错误处理函数:app.handle_user_exceptionapp.handle_exception

所以你可以在你的应用配置中设置PROPAGATE_EXCEPTIONS

app.config['PROPAGATE_EXCEPTIONS'] = True

解决方案 #2

我将采用的最终解决方案是根据最近的建议 found here 来增强 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

【讨论】:

【参考方案3】:

您是否尝试添加:

"WSGIPassAuthorization On"

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

【讨论】:

以上是关于Flask Restful NoAuthorizationError 缺少授权标头的主要内容,如果未能解决你的问题,请参考以下文章

Flask-RESTful扩展

Flask 学习-23.restful 接口开发

flask-restful 组件

七十七:flask.Restful之flask-Restful参数验证

Flask-Restful

Flask (flask-restful) 和 MySQLdb (PyMySQL) 的奇怪并发问题