Flask Restful NoAuthorizationError缺少授权标头

时间:2018-08-30 00:31:35

标签: python flask jwt gunicorn flask-restful

我正在使用Python 3.6在生产模式下的服务器上运行Flask Restful,并命中了需要jwt auth的端点,但是我一直收到“ NoAuthorizationError Missing Authoring 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的问题,但是没有成功。

3 个答案:

答案 0 :(得分:3)

对于遇到此错误的其他任何人,这实际上是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

答案 1 :(得分:2)

您看到的错误意味着授权标头没有将其添加到flask应用程序中。要么没有发送,要么有东西正在剥离,然后烧瓶才能到达它。

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

答案 2 :(得分:1)

您尝试添加:

"WSGIPassAuthorization On"

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