首页 > 解决方案 > 获取不发送 Cookie

问题描述

当我在浏览器的控制台(在开发人员工具中)中使用以下 js 片段(尝试过 chrome、firefox 和 edge)时,在获取发送 cookie 时遇到问题:

fetch('http://127.0.0.1:3010/check', {
  credentials: 'include'
  method: 'GET'
})
  .then(res=>res.json())
  .then(jsonobj=>{console.log(jsonbj)});

这是我处理 api 请求的快速代码:

var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var cors = require('cors');

var app = express();
app.use(cors({
    credentials: true,
    origin: 'https://www.youtube.com'
));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

app.get('/check', (req, res)=>{
  console.log(JSON.stringify(req.cookies));
  res.json({
    message: "COOL"
  });
});

fetch 调用成功,消息 COOL 被记录到浏览器控制台。但是,NodeJS 控制台会打印空对象 {} 或空 cookie。

例如,当我在http://youtube.com/的控制台中运行 fetch 请求时,我希望浏览器将 localhost 上的 cookie 发送到我的 express 服务器(我这样做是为了模拟跨站点请求中的 cookie 发送)。

编辑 1:我的本地主机上的一些 cookie 也未设置 SameSite 并且 mdn 文档说这些 cookie 也可以在跨站点请求中发送到服务器

如果未设置该标志或浏览器不支持该标志,则默认行为是将 cookie 包含在任何请求中,包括跨域请求。

来自 mdn 文档的片段是错误的,或者浏览器对 SameSite 的实现不一致。我很困惑。

编辑 2:此页面https://textslashplain.com/2019/09/30/same-site-cookies-by-default/

在 Chrome 80 及更高版本中,cookie 将默认为 SameSite=Lax。这意味着 cookie 将仅在第一方上下文中自动发送,除非它们通过显式设置 None 指令来选择退出:

那么关于 SameSite 的默认值的 mdn 文档真的不正确吗?

编辑 3:我已提议对 mdn 文档进行编辑,并已被接受。

标签: javascriptnode.jscookiescross-domain

解决方案


在使用此答案之前,请查看问题的编辑。现在,如果 cookie 未设置SameSite属性,我们将无法再发送带有跨站点请求的 cookie ,因为浏览器已将 SameSite 的默认值更改为 lax。以下是 chrome 补丁说明的快照(对于稳定版 80,尽管 79 版 beta 版将提供 beta 测试,因为 google 认为此更改将具有破坏性,并可能导致某些 web 应用程序行为不正确,因此显示警告太)在https://support.google.com/chrome/a/answer/7679408#76

默认情况下使用 SameSite 的 Cookie,Chrome 80 中的 Secure SameSite=None cookie 从 Chrome 80 开始,未指定 SameSite 属性的 cookie 将被视为 SameSite=Lax。仍然需要在跨站点上下文中传递的 Cookie 可以显式请求 SameSite=None。它们还必须标记为安全并通过 HTTPS 交付。将为需要配置 Chrome 以暂时恢复到旧 SameSite 行为的企业提供策略。

目前 Firefox 和 Edge 也显示了类似的行为。要在跨源请求中发送 cookie,我们必须将 SameSite 属性显式设置为 None 为:

Set-Cookie: key=value; SameSite=None; Secure

另外,请注意 Secure 是强制性的,否则它将被视为 Lax cookie。仅当您确实确定自己在做什么并准确处理跨站点请求伪造时,才使用无选项!

我曾提议对 Http Cookie ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies )的 mdn 文档进行更改,并且更改已发布。现在 mdn 文档说:

以前,如果 SameSite 属性未设置或浏览器不支持,则默认行为是在任何请求中包含 cookie — 包括跨域请求。

但是,新版本的浏览器默认为 SameSite=Lax。换句话说,现在处理没有设置 SameSite 属性的 cookie,就好像 SameSite 属性的值设置为 Lax 一样——这意味着 cookie 将仅在第一方上下文中自动发送。要指定在同站点和跨域请求中都发送 cookie,该值必须显式设置为 None。


推荐阅读