即使在Flask应用程序中启用了CORS,也无法设置Cookie [英] Cookies not being set even with CORS enabled in Flask app
问题描述
请注意:类似这样的问题很多,但没有一个对我有用,这就是为什么我问这个问题.
我的REST API是Flask应用程序.我的/login
端点使用JWT,并在客户端的cookie中设置访问和刷新令牌.
My REST API is a Flask application. My /login
endpoint uses JWTs and sets the access and refresh tokens in the client's cookies.
我在 127.0.0.1:5000
上运行Flask,并且在 127.0.0.1:8080
上运行前端.
I am running Flask on 127.0.0.1:5000
and the frontend on 127.0.0.1:8080
.
@auth.api(
http_path='/login',
http_method='POST',
)
def login(email, password):
# ...
access_token = create_access_token(identity=user.id, fresh=True, expires_delta=app.config['JWT_ACCESS_TOKEN_EXP'])
refresh_token = create_refresh_token(identity=user.id, expires_delta=app.config['JWT_REFRESH_TOKEN_EXP'])
resp = jsonify({'login': True})
set_access_cookies(resp, access_token)
set_refresh_cookies(resp, refresh_token)
# ...
return resp
我的应用启用了CORS:
My app has CORS enabled:
from flask_cors import CORS
# ...
cors = CORS()
def create_app():
app = Flask(__name__)
# ...
cors.init_app(app)
# ...
return app
客户代码
$.ajax({
method: "POST",
url: "http://127.0.0.1:5000/login",
data: JSON.stringify({email: 'myemail', password: 'mypassword'}),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
console.log('logged in!');
}
});
问题
未在Firefox,Chrome或Edge中设置cookie.但是,使用浏览器的开发工具时,我可以在响应标题"中看到cookie,但"cookie"下的存储"部分没有任何显示.
The Problem
The cookies are not being set in Firefox, Chrome nor Edge. However I can see the cookies in the Response Headers when using the browser's dev tools, but nothing appears in the Storage section, under Cookies.
我尝试了多种方法:
- 在后端设置
cors = CORS(supports_credentials = True)
,并在前端设置xhrFields:{withCredentials:true}
. - 在前端设置
crossDomain:true
- 确保没有cookie被浏览器的设置阻止
- 专门在
127.0.0.1
而不是localhost
上运行
- setting
cors=CORS(supports_credentials=True)
on the backend and settingxhrFields:{ withCredentials: true}
on the frontend. - setting
crossDomain: true
on the frontend - making sure no cookies are being blocked by the browser's settings
- running specifically on
127.0.0.1
instead oflocalhost
我需要某种前端代理吗?必须有一个更简单的解决方案.
Do I need some sort of proxy for the frontend? There must be an easier solution.
推荐答案
因此,经过很多头痛之后,我才知道出了什么问题.部分原因是我的错,也是潜在的错误.
So after a lot of headaches, I figured out what's wrong. It's partially my fault but also a potential bug.
我正在使用 flask-jwt-extended
库进行JWT身份验证;有一些关于JWT的环境变量,它们的值在 set_access_cookies
函数中使用.
I am using the flask-jwt-extended
library for my JWT authentication; there are some environment variables regarding JWTs whose values are used in the set_access_cookies
function.
通常,您的Flask应用程序配置是这些变量的位置,但是,我选择使用单独的.env文件并从中加载环境变量.问题是,对于 MY_VAR = False
之类的东西, MY_VAR
将获得字符串值"False" ,而不是布尔标志.
Typically, your Flask application config is the place for these variables, however, I had opted for using a separate .env file and loading my environment variables from it. The issue was that for things like MY_VAR=False
, MY_VAR
would get the string value "False" instead of a boolean flag.
对于 JWT_COOKIE_SECURE
来说,它表现得特别差-该变量的值在 set_access_cookies
函数中使用,该函数本身将 set_cookie
函数用于 Request
对象-如果您为安全"字段传递字符串,则cookie乱码,浏览器很可能会忽略它.
This manifested itself particularly poorly for JWT_COOKIE_SECURE
- the value of this variable is used in the set_access_cookies
function which itself uses the set_cookie
function for a Request
object - if you pass a string for the Secure field, it garbles the cookie and your browser will most likely ignore it.
因此,乱码的cookie看起来像这样:
So a garbled cookie would look something like this:
('Set-Cookie', 'access_token_cookie=yourtoken; Domain=localhost.example.com; Secure; HttpOnly; Path=/')
请注意, Secure
字段应为空还是不存在(如果为false)时该字段为空.
Notice how the Secure
field is empty, when it should either be a boolean or not there at all (if false).
我希望这会有所帮助!
这篇关于即使在Flask应用程序中启用了CORS,也无法设置Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!