重定向后,浏览器不会从带有 www 的域发送 cookie

Browser doesn't send the cookie from domain with www after redirect

我的网站有一个暂存版本 beta.example.com。我最近使用以下设置添加了 cookie 身份验证:

response.cookie(tokenName, token, {
  httpOnly: true,
  expires: new Date(Date.now() + (tokenExpirationSec * 1000))
})

暂存身份验证有效。

当我将代码部署到生产环境时,cookie 已成功设置(通过 Set-Cookie header),但未在 server-side 请求中发送到服务器。因此,当我刷新登录状态时,它会消失,但会保留在 client-side 请求中。

值得注意的是,有一个从 example.comwww.example.com 的 301 重定向。此外,host header 已投入生产 www.example.com

我最终通过在设置 cookie 时添加 domain 参数解决了这个问题,如下所示:

response.cookie(tokenName, token, {
  httpOnly: true,
  expires: new Date(Date.now() + (tokenExpirationSec * 1000)),
  domain: '.example.com'
})

但是我并不完全理解问题的根源。根据MDN

Domain specifies allowed hosts to receive the cookie. If unspecified, it defaults to the host of the current document location, excluding subdomains. If Domain is specified, then subdomains are always included.

因此,当我在没有显式设置 domain 的情况下使用 beta.example.com 进行暂存时,根据 MDN,隐式 domain 将是 example.com,而 beta.example.com 将是排除在外。但身份验证确实在暂存中起作用!

但我在生产中遇到了与 www.example.com 相同的情况,为什么它在生产中不起作用?

这是执行重定向的 nginx 配置:

server {
    listen       80 default_server;

    server_name beta.example.com;

    location / {
        include proxy_pass.inc;
    }
}

server {
    listen       80 default_server;

    server_name www.example.com;

    location / {
        include proxy_pass.inc;
    }
}

server {
    listen       80;
    server_name  example.com;
    return       301 https://www.example.com$request_uri;
}

我认为您误解了 MDN documentation

If unspecified, it defaults to the host of the current document location, excluding subdomains.

意思是如果你在 beta.example.com,那么 Domain 将被设置为值 beta.example.com。这将从其他子域排除 cookie。

如果您想在所有子域上使用 cookie,您必须明确设置 Domain