仅在生产中缺少授权标头

Posted

技术标签:

【中文标题】仅在生产中缺少授权标头【英文标题】:Missing Authorization Header in production only 【发布时间】:2021-09-20 10:50:45 【问题描述】:

我有以下工作流程:

我有一个api/token [POST],它接受表单数据(电子邮件和密码)并返回和访问令牌以及刷新令牌。

然后我有另一个端点api/users/info [GET](带有标题'Authorization': 'Bearer ...)返回用户信息。在本地测试时,两个端点都可以工作。

在对我部署的服务器进行测试时,只有获取令牌的方法有效。

这是api/users/info的代码:

@API_BP.route('/users/info', methods=['GET'])
@fresh_jwt_required
def users_info():

    user_identity = get_jwt_identity()
    curr_user = (SDB.session.query(User)
                 .filter_by(email=user_identity).one_or_none())
    return jsonify(
        'greeting': 'Hello, World!',
        'foo': 'bar',

    )

此外,这是我的配置:

JWT_TOKEN_LOCATION = ['cookies', 'headers']
JWT_COOKIE_CSRF_PROTECT = True
JWT_COOKIE_SECURE = True 
JWT_ACCESS_COOKIE_NAME = "my_access_cookie"
JWT_REFRESH_COOKIE_NAME = "my_refresh_cookie"
JWT_ACCESS_CSRF_COOKIE_NAME = "my_csrf_access_token"
JWT_REFRESH_CSRF_COOKIE_NAME = "my_csrf_refresh_token"
JWT_ACCESS_CSRF_HEADER_NAME = "X-MY-TOKEN"

我得到的错误是:


    "msg": "Missing JWT in cookies or headers (Missing cookie \"my_access_cookie\"; Missing Authorization Header)"

我正在使用 Postman 来访问这些端点。我已在授权下设置了api/token 收到的令牌。这是python中的样子:

import requests

url = "http://my_url.com/api/users/info"

payload = 
headers = 
  'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhrtyuzI1NiJ9.eyJpYXQiOjE2MjU5MTg0MTEsIm5iZiI6MTYyNTkxODQxMSwianRpfghZi00YTcyLWIxZTYtZGMxYTRjNDhkOThhIiwiZXhwIjoxNjI1OTE5NjExLCJpZGVudGl0eSI6ImFsZnJlZG9Adml2ZWJlbmVmaXRzLmNvbSIsImZyZXNoIjp0cnVlLCsdfghXBlIjoiYWNjZXNzIiwiY3NyZiI6ImQyNTQ0NjY0LTFlOGUtNDY5NS1hY2I4LTE2MzIxMDZlNDY0MiJ9.WT-EWlMtZZKoNyiXYxa3xdfghjg7r7ys'


response = requests.request("GET", url, headers=headers, data = payload)

print(response.text.encode('utf8'))

如何确保第二个请求 GET 在 prod 中有效?

【问题讨论】:

您使用的是哪个 REST API 客户端?邮差?你能把里面的所有cookies都删掉吗? 你在底部代码中使用了 Bearer 令牌,而在你的配置中你有 JWT_ACCESS_COOKIE_NAME = "my_access_cookie" 你能确保它们匹配 我正在使用邮递员来访问这些端点。再次发送到 localhost/prod 时会发生差异。它适用于本地而不是产品。我已清除所有 cookie。对于第二条评论,您是什么意思?将 Bearer 替换为 my_access_cookie ? 是的,我就是这个意思 我试过了。不用找了。我很确定配置仅在尝试通过 cookie 访问端点时才重要,而不是标题 【参考方案1】:

问题是verify_jwt_in_request() 会寻找标题Authorization 而不是X-Forwarded-Authorization

在本地,标头为 Authorization,但在生产中,因为我们使用的是 docker/nginx,标头更改为 X-Forwarded-Authorization。我解决这个问题的方法是设置配置JWT_HEADER_NAME = "X-Forwarded-Authorization"

【讨论】:

【参考方案2】:

如果您在生产环境中使用 modwsgi,您可能需要确保启用了 WSGIPAssAuthorization On 配置选项。根据您在 prod (Apache/nginx/uwsgi/unicorn/etc) 中运行烧瓶应用程序所使用的软件,可能会有类似的选项。

【讨论】:

我提交了一个答案,你认为它相关吗?就像我设置 WSGIPAssAuthorization On 一样,标题不会从 Authorization 转换 -> X-Forwarded-Authorization 吗?

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

为啥缺少授权标头?

PHP POST 请求中缺少授权标头

使用 JWT 缺少授权标头

POST请求中缺少授权标头[重复]

如果通过 Zuul API 网关发送请求,则缺少授权标头

Flask Restful NoAuthorizationError 缺少授权标头