【问题标题】:httpOnly cookies in cross-domain requests not being sent未发送跨域请求中的 httpOnly cookie
【发布时间】:2021-04-30 18:27:11
【问题描述】:

我真的很抱歉又问了一个 CORS 问题,但我被卡住了,我不明白为什么。

我有任何 API,在登录时会以 Set-Cookie 标头响应,该标头会使用我的用户信息设置 cookie。这就是响应的样子:

来自api.somesite.com的回复

Access-Control-Allow-Credentials: true
Connection: keep-alive
Content-Length: 183
Content-Type: text/html; charset=utf-8
Date: Mon, 19 Apr 2021 19:55:02 GMT
Set-Cookie: socialAccesstoken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5MDk3NzQzNjkxNjU1MTY4MCIsInVzZXJuYW1lIjoiY3JlYXRpdmlpaSIsImRpc3BsYXlOYW1lIjoiTGVvIDjvuI_ig6MiLCJ1cmwiOiJodHRwczovL3QuY28vWjNBM01xaFBDbiIsInBob3RvIjoiaHR0cHM6Ly9wYnMudHdpbWcuY29tL3Byb2ZpbGVfaW1hZ2VzLzEzNzExMzQ3MjY0NzI0MTMxODYvZ0Q5Sk5lVU1fbm9ybWFsLmpwZyIsInByb3ZpZGVyIjoidHdpdHRlciIsImlhdCI6MTYxODg2MjEwMiwiZXhwIjoxNzA1MjYyMTAyfQ.Q7yWf-ywoZ-rWOhYseKTt_0V2_AlEMQ-cCL2rlRNm_U; Max-Age=86400; Path=/; Expires=Tue, 20 Apr 2021 19:55:02 GMT; HttpOnly
Vary: Origin
X-Powered-By: Express

Cookie 设置成功,我可以在Application 选项卡中查看api.somesite.com

然后我尝试从同一域上的页面发出请求:

somesite.comapi.somesite.com 的请求

Response

HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://somesite.com:8000
Vary: Origin
Access-Control-Allow-Credentials: true
Token-Expired: true
Content-Type: application/json; charset=utf-8
Content-Length: 196
ETag: W/"c4-HQkmHNLuibgvd4gvz0JqjTLKjFU"
Date: Mon, 19 Apr 2021 19:59:18 GMT
Connection: keep-alive

Request
Host: api.somesite.com:3000
Connection: keep-alive
Content-Length: 143
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36
content-type: application/json
Accept: */*
Origin: http://somesite.com:8000
Referer: http://somesite.com:8000/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8
Cookie: socialAccesstoken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5MDk3NzQzNjkxNjU1MTY4MCIsInVzZXJuYW1lIjoiY3JlYXRpdmlpaSIsImRpc3BsYXlOYW1lIjoiTGVvIDjvuI_ig6MiLCJ1cmwiOiJodHRwczovL3QuY28vWjNBM01xaFBDbiIsInBob3RvIjoiaHR0cHM6Ly9wYnMudHdpbWcuY29tL3Byb2ZpbGVfaW1hZ2VzLzEzNzExMzQ3MjY0NzI0MTMxODYvZ0Q5Sk5lVU1fbm9ybWFsLmpwZyIsInByb3ZpZGVyIjoidHdpdHRlciIsImlhdCI6MTYxODg2MTQ2MiwiZXhwIjoxNzA1MjYxNDYyfQ.BpmQzWWYuBHLQQh6VpatflBsQUv2A0ahLqt1UgYOq8Q

如您所见,cookie 已正确发送。

但是那么如果我将我的 api 切换到 api.differentsite.com 并提出相同的请求:

api.differentsite.com的回复

HTTP/1.1 200 OK
X-Powered-By: Express
Vary: Origin
Access-Control-Allow-Credentials: true
Set-Cookie: socialAccesstoken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Ijk5MDk3NzQzNjkxNjU1MTY4MCIsInVzZXJuYW1lIjoiY3JlYXRpdmlpaSIsImRpc3BsYXlOYW1lIjoiTGVvIDjvuI_ig6MiLCJ1cmwiOiJodHRwczovL3QuY28vWjNBM01xaFBDbiIsInBob3RvIjoiaHR0cHM6Ly9wYnMudHdpbWcuY29tL3Byb2ZpbGVfaW1hZ2VzLzEzNzExMzQ3MjY0NzI0MTMxODYvZ0Q5Sk5lVU1fbm9ybWFsLmpwZyIsInByb3ZpZGVyIjoidHdpdHRlciIsImlhdCI6MTYxODg2MjYzMSwiZXhwIjoxNzA1MjYyNjMxfQ.MvOLarBw_Mz-h26WvOrOqyE0IaDQEnIqp2xLUiFqAZQ; Max-Age=86400; Path=/; Expires=Tue, 20 Apr 2021 20:03:51 GMT; HttpOnly
Content-Type: text/html; charset=utf-8
Content-Length: 183
Date: Mon, 19 Apr 2021 20:03:51 GMT
Connection: keep-alive

(根据 Chrome 中的“应用程序”选项卡,cookie 已正确设置为 api.differentsite.com:3000

然后我尝试从somesite.com发出请求:

Response

HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://somesite.com:8000
Vary: Origin
Access-Control-Allow-Credentials: true
Content-Type: application/json; charset=utf-8
Content-Length: 147
ETag: W/"93-2hkHY0W/lJkUQBK+JwrKp/OTCro"
Date: Mon, 19 Apr 2021 20:03:26 GMT
Connection: keep-alive

Request
POST /api HTTP/1.1
Host: api.differentsite.com:3000
Connection: keep-alive
Content-Length: 143
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36
content-type: application/json
Accept: */*
Origin: http://somesite.com:8000
Referer: http://somesite.com:8000/
Accept-Encoding: gzip, deflate
Accept-Language: en-GB,en-US;q=0.9,en;q=0.8

没有发送cookie,所以授权失败。

为什么会这样?这应该可行,不是吗?

我的请求如下所示:

  const headers = new Headers();
  headers.append("Content-Type", "application/json");

  const result = await fetch(endpoint!, {
    method: "POST",
    headers,
    body,
    redirect: "follow",
    credentials: "include",
  }).then((response) => response.json());

我一遍又一遍地检查,我确信这些设置是正确的。

我遵循了this question 上的建议,但没有奏效。我不确定我应该在我的请求中添加什么 Access-Control-Allow-Headers

【问题讨论】:

    标签: cookies authorization cross-domain


    【解决方案1】:

    看来我只需要一晚睡眠。

    问题是由于我的 cookie 缺少正确的设置造成的。要在 cross-domain 请求中发送 httpOnly cookie,他们需要:

    • same-site 设置为 none
    • secure 设置为 true

    所以我确保在生产时在 cookie 上设置了这两个值:

        sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax',
        secure: process.env.NODE_ENV === 'production' ? true : false,
    

    它开始工作了。

    编辑:

    虽然这是正确答案,但 Safari 现在似乎默认阻止第三方 cookie,这意味着如果客户端是 Safari,则不会发送任何 cookie。这可以在设置中关闭,但默认是开启的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-05
      • 2019-02-11
      • 1970-01-01
      • 2017-06-20
      • 2020-11-19
      • 1970-01-01
      • 2019-02-02
      • 2020-07-29
      相关资源
      最近更新 更多