配置 Axios 和 Flask 以使用 CORS 和 cookie

Posted

技术标签:

【中文标题】配置 Axios 和 Flask 以使用 CORS 和 cookie【英文标题】:Configure Axios and Flask to use CORS with cookies 【发布时间】:2018-12-06 10:45:13 【问题描述】:

前端运行在localhost:3000 服务器运行在localhost:9000

我可以在不访问 cookie 的情况下发出 CORS 请求。

Axios 请求示例

axios.post(SERVER+'/createUser', params)
        .then( resp=>
            //not important
        );

(工作:能够从其他服务器访问资源)

我无法保存/发送服务器 localhost:9000 设置的 HttpOnly cookie [会话实现]

预期的流程

致电localhost:9000/authenticate

localhost:9000/authenticate 返回带有 HttpOnly cookie 的响应

localhost:9000的后续请求携带此cookie

为了尝试使用 axios 访问此 cookie,我添加了标题 withCredentials:true 由documentation for axios 引用。为清楚起见:

let headers = 
    withCredentials:true

export function authenticate(creds)
    return dispatch => 
        axios.post(SERVER+'/authenticate', creds, headers)
            .then( resp => 
                //not important
            );
    ;

之后我收到以下错误:

未能加载http://localhost:9000/authenticate:响应 预检请求未通过访问控制检查: 响应中的“Access-Control-Allow-Origin”标头不能是 当请求的凭据模式为“包含”时,通配符“*”。起源 'http://localhost:3000' 因此不允许访问。这 XMLHttpRequest 发起的请求的凭证模式是 由 withCredentials 属性控制。

为清楚起见,发送第一个 (OPTIONS) 请求并在“成功”响应后引发错误。选项请求:

我的服务器使用Flask-Cors 库,在阅读了cookie documentation 和其他一些链接之后,这就是为CORS 设置服务器的方式

... normal app init
app = Flask(__name__, static_url_path='/static')
...
cors = CORS(app, origins=["http://localhost:3000"], headers=['Content-Type'], expose_headers=['Access-Control-Allow-Origin'], supports_credentials=True)
...
@app.route('/authenticate', methods=['POST'])
def authenticate():
    ...

我只将该方法设置为 POST,因为 (1) cookie documentation 也将其限制为 POST 并且 (2) OPTIONS 请求似乎通过(如图像所引用的那样)和 (3) 当我确实包含 OPTIONS 作为路由的一种可能方法,当发送第一个请求时,它会进入该方法,我不知道要返回什么,所以如果有人知道包含 OPTIONS 方法时的正确响应是什么,请发布。

其他链接

https://github.com/axios/axios/issues/569

Why does my javascript get a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error when Postman does not?

CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true

Set-Cookie header has no effect

【问题讨论】:

withCredentials=true 后的错误信息非常清楚。在这种情况下,您不能使用通配符作为此标头的值,并且必须在服务器端动态设置此值。否则请查看 Access-Control-Request-Headers 和 Access-Control-Allow-Headers。 如果我错了@marekful,请纠正我,但是 origins=["localhost:3000"] 不能做到这一点,响应头也不包括'Vary:Origin'吗? 尝试发送带有请求的Access-Control-Request-Headers: Cookie, Set-Cookie 和带有响应的Access-Control-Allow-Headers: Cookie, Set-Cookie 【参考方案1】:

代码看起来像您将 withCredentials 定义为 HTTP 标头。但这并不是它的工作原理。

withCredentials实际上是一个启用http头的选项,但它本身不是http头。

尝试像这样创建承诺:

const axiosWithCookies = axios.create(
  withCredentials: true
);
const promise = axiosWithCookies.get(url);

生成的 http 标头实际上如下所示。 但是您不必手动添加它。如果您像上面那样创建 axios 实例,这将得到处理。

Cookie: JSESSIONID=...

【讨论】:

以上是关于配置 Axios 和 Flask 以使用 CORS 和 cookie的主要内容,如果未能解决你的问题,请参考以下文章

使用 Axios 上传文件时出现 JavaScript CORS 错误

使用 Vue Axios (CORS) 发送/存储会话 cookie 时出现问题

使用 axios cors 策略错误配置 nodejs rest api 服务器和 vue 项目

再遇CORS -- 自定义HTTP header的导致跨域

CORS 配置 Flask、Angular 和 NGINX

Flask,Axios POST 返回网络错误