问题描述
我有以下工作流程:
我有一个 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 中有效?
解决方法
如果您在生产中使用 modwsgi,您可能需要确保启用了 WSGIPAssAuthorization On
配置选项。可能有类似的选项,具体取决于您在 prod (Apache/nginx/uwsgi/unicorn/etc) 中使用什么软件来运行 Flask 应用程序。
问题在于 verify_jwt_in_request()
会查找标题 Authorization
而不是 X-Forwarded-Authorization
。
在本地,标头将是 Authorization
,但在生产中,因为我们使用 docker/nginx,标头更改为 X-Forwarded-Authorization
。我解决这个问题的方法是设置配置 JWT_HEADER_NAME = "X-Forwarded-Authorization"