【问题标题】:Browser refuses to honor Set-Cookie header from cross-origin response浏览器拒绝接受来自跨源响应的 Set-Cookie 标头
【发布时间】:2023-02-09 17:03:25
【问题描述】:

我正在努力让我的前端设置一个通过后端发送的 http cookie(并在后续请求中将其发送到后端)。特别想设置一个 refreshToken 用于身份验证目的。

我知道我的后端正在正确发送 cookie,因为登录响应的标头如下所示。

Set-Cookie: refreshToken=someLongRefreshToken; Path=/; Expires=Thu, 19 Jan 2023 20:12:52 GMT; HttpOnly; SameSite=Lax

这就是我从前端发送请求的方式(通过拦截器设置身份验证令牌)。

const axiosAuth = axios.create({
  validateStatus: (status: number) => {
    return status >= 200 && status < 300; // default (200 - 299);
  },
  headers: {
    Accept: `application/json`,
    'Content-Type': 'application/json',
    withCredentials: true,
  },
});

然后在某个组件中

let res = await axiosAuth.get('http://localhost:9922/someRoute');

几张纸条

  1. 我相当确定我的问题出在前端。如果我登录并通过 Postman 发送另一个请求,它就可以正常工作。它获取 http cookie 并在后续请求中将其传回 api。
  2. 虽然我在响应标头中看到了 cookie set-cookie,但我在开发工具(应用程序/cookie)中没有看到它。
  3. Cookie 未在本地设置为安全(因此我不必使用 https)
  4. 我已确保我的 api 接受必要的标头/cors 内容。这是我的 api 路由器,这样您就可以看到我正在设置的标头。
    r.Use(cors.Handler(cors.Options{
        AllowedOrigins:   []string{"http://localhost:3002"},
        AllowedMethods:   []string{"GET", "POST", "OPTIONS"},
        AllowedHeaders:   []string{"Accept", "Access-Control-Allow-Credentials", "Authorization", "WithCredentials", "Content-Type", "X-CSRF-Token", "SelectedGroup", "Allow-Credentials", "Cookie"},
        ExposedHeaders:   []string{"Set-Cookie"},
        AllowCredentials: true,
    }))
    

    如果我需要提供任何其他信息,请告诉我。

【问题讨论】:

  • 1. 尝试暴露 Set-Cookie 标头无处可去,因为它是 forbidden response-header name。 2.关于Cookie的类似评论,是forbidden request header。 3. 对于成功设置cookie的跨域请求,服务器的CORS配置必须允许凭据(Access-Control-Allow-Credentials: true)。
  • @jub0bs 我已经将 "Access-Control-Allow-Credentials" 添加到允许的标头中。我仍然没有在后端收到 cookie。还删除了您提到的其他两个没用的。
  • 我现在注意到您的客户端代码不正确:withCredentials 不是请求标头,而是请求的属性。参见axios-http.com/docs/req_config。解决这个问题,看看情况是否有所改善。
  • @jub0bs 啊,谢谢,是 withCredentials 在错误的地方。这解决了问题。谢谢。
  • 好东西。当我在允许的请求标头列表中看到 withCredentials 时,我最初感到困惑,但现在我明白了。不用说,您可以安全地将其从该列表中删除。

标签: go cookies axios cors


【解决方案1】:

您在客户端代码的错误位置使用了 withCredentials:它不是请求标头,而是请求的属性。代替

const axiosAuth = axios.create({
  validateStatus: (status: number) => {
    return status >= 200 && status < 300;
  },
  headers: {
    Accept: `application/json`,
    'Content-Type': 'application/json',
    withCredentials: true, // incorrect
  },
});

你应该有

const axiosAuth = axios.create({
  validateStatus: (status: number) => {
    return status >= 200 && status < 300;
  },
  headers: {
    Accept: `application/json`,
    'Content-Type': 'application/json',
  },
  withCredentials: true, // correct
});

【讨论】:

    猜你喜欢
    • 2018-10-26
    • 1970-01-01
    • 2023-03-25
    • 2014-08-24
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 2016-09-16
    • 2017-12-24
    相关资源
    最近更新 更多