即使在 Flask 应用程序中启用了 CORS,也不会设置 Cookie
Cookies not being set even with CORS enabled in Flask app
请注意:有很多这样的问题,但其中 none 对我有用,这就是我问这个问题的原因。
我的 REST API 是一个 Flask 应用程序。我的 /login
端点使用 JWT 并在客户端的 cookie 中设置访问和刷新令牌。
我是 运行 127.0.0.1:5000
的 Flask 和 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:
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。但是,当使用浏览器的开发工具时,我可以在响应 Headers 中看到 cookie,但在 Cookies 下的存储部分中什么也没有出现。
我试过很多东西:
- 在后端设置
cors=CORS(supports_credentials=True)
,在前端设置 xhrFields:{ withCredentials: true}
。
- 在前端设置
crossDomain: true
- 确保没有 cookie 被浏览器设置阻止
- 运行 特别是
127.0.0.1
而不是 localhost
我需要某种前端代理吗?必须有更简单的解决方案。
所以在经历了很多令人头疼的事情之后,我想出了问题所在。这部分是我的错,但也是一个潜在的错误。
我正在使用 flask-jwt-extended
库进行 JWT 身份验证;有一些关于 JWT 的环境变量,其值在 set_access_cookies
函数中使用。
通常,您的 Flask 应用程序配置是这些变量的位置,但是,我选择使用单独的 .env 文件并从中加载我的环境变量。问题是,对于 MY_VAR=False
、MY_VAR
之类的东西,将获得 字符串值 "False" 而不是布尔标志。
这对于 JWT_COOKIE_SECURE
表现得特别差 - 这个变量的值用在 set_access_cookies
函数中,它本身使用 set_cookie
函数用于 Request
对象- 如果您为安全字段传递一个字符串,它会使 cookie 乱码,您的浏览器很可能会忽略它。
所以乱码 cookie 看起来像这样:
('Set-Cookie', 'access_token_cookie=yourtoken; Domain=localhost.example.com; Secure; HttpOnly; Path=/')
注意 Secure
字段是空的,它应该是布尔值或根本不存在(如果为 false)。
希望对您有所帮助!
请注意:有很多这样的问题,但其中 none 对我有用,这就是我问这个问题的原因。
我的 REST API 是一个 Flask 应用程序。我的 /login
端点使用 JWT 并在客户端的 cookie 中设置访问和刷新令牌。
我是 运行 127.0.0.1:5000
的 Flask 和 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:
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。但是,当使用浏览器的开发工具时,我可以在响应 Headers 中看到 cookie,但在 Cookies 下的存储部分中什么也没有出现。
我试过很多东西:
- 在后端设置
cors=CORS(supports_credentials=True)
,在前端设置xhrFields:{ withCredentials: true}
。 - 在前端设置
crossDomain: true
- 确保没有 cookie 被浏览器设置阻止
- 运行 特别是
127.0.0.1
而不是localhost
我需要某种前端代理吗?必须有更简单的解决方案。
所以在经历了很多令人头疼的事情之后,我想出了问题所在。这部分是我的错,但也是一个潜在的错误。
我正在使用 flask-jwt-extended
库进行 JWT 身份验证;有一些关于 JWT 的环境变量,其值在 set_access_cookies
函数中使用。
通常,您的 Flask 应用程序配置是这些变量的位置,但是,我选择使用单独的 .env 文件并从中加载我的环境变量。问题是,对于 MY_VAR=False
、MY_VAR
之类的东西,将获得 字符串值 "False" 而不是布尔标志。
这对于 JWT_COOKIE_SECURE
表现得特别差 - 这个变量的值用在 set_access_cookies
函数中,它本身使用 set_cookie
函数用于 Request
对象- 如果您为安全字段传递一个字符串,它会使 cookie 乱码,您的浏览器很可能会忽略它。
所以乱码 cookie 看起来像这样:
('Set-Cookie', 'access_token_cookie=yourtoken; Domain=localhost.example.com; Secure; HttpOnly; Path=/')
注意 Secure
字段是空的,它应该是布尔值或根本不存在(如果为 false)。
希望对您有所帮助!