即使在Flask应用程序中启用了CORS,也无法设置Cookie [英] Cookies not being set even with CORS enabled in Flask app

查看:50
本文介绍了即使在Flask应用程序中启用了CORS,也无法设置Cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意:类似这样的问题很多,但没有一个对我有用,这就是为什么我问这个问题.

我的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 setting xhrFields:{ 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 of localhost

我需要某种前端代理吗?必须有一个更简单的解决方案.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆