我的 NodeJS 服务器出现了一个奇怪的情况:似乎在 Google 上搜索网站会让用户退出。
主页是https://emocoes.org/pt/inicio
。我登录网站后,主页会显示用户版本,例如“内容列表”按钮。
我打开一个新标签页,在 Google 上搜索该网站并点击链接。现在主页不再显示用户版本。就好像我已经退出了一样。当我刷新主页的第一个标签页时,它还会显示公共版本。我检查了会话存储中的会话 cookie 是否仍然存在。
Google 查询的 URL 是:
我没有发现此链接存在任何问题。
我将此跟踪添加到服务器的主页路由中:
router.get("/pt/inicio", async (req, res) => {
console.log("URL = %o", req.originalUrl);
console.log("query = %o", req.query);
console.log("User = %o", req.user);
// The result after the Google URL is:
//[2022-06-03T17:40:21.308Z] URL = '/pt/inicio'
//[2022-06-03T17:40:21.308Z] query = {}
//[2022-06-03T17:40:21.309Z] User = undefined
...
});
由于会话存在于 MongoDB 存储中,因此点击 Google 链接就像删除浏览器中的 cookie 一样。我在 macOS 上使用 Safari,Windows 和 Google Chrome 上的用户也会发生同样的事情。
我该如何调试此问题?
PS:如果你想自己尝试,请在 dispostable.com 创建一个临时电子邮件地址,然后使用它在https://emocoes.org/en/entrar。
更新
设置 cookie 的 NodeJS 服务器代码是:
const express = require('express');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const max_session_ms = 365 * 24 * 60 * 60 * 1000;
app.use(
session({
cookie: {
maxAge: max_session_ms,
sameSite: "strict",
},
store: store,
secret: ...,
signed: true,
resave: false, // Unknown effect. See https://github.com/expressjs/session#resave
saveUninitialized: false, // Save only explicitly, e.g. when logging in.
httpOnly: true, // Don't let browser javascript access cookies.
secure: true
})
);
答案1
出现此问题的原因似乎是您的网站使用 设置了会话 cookie SameSite=Strict
。
cookieSameSite
属性是一种安全功能,如果您的网站有严格的安全要求,您可能需要它。您可能不应该理会它,如果没有,请将其保留为未设置状态。当SameSite
并且Strict
您单击指向您网站的另一个网站上的链接时,浏览器将不会发送 cookie。当 时Lax
,它会在单击链接时发送 cookie,但当另一个网站嵌入您网站的图像时,它不会发送 cookie。更多信息可在相关 MDN 页面以及Cookie 标准草案(分散在几个部分,例如 5.2、5.4.7 和 8.8)。
如果您使用Strict
,您必须做好应对奇怪事情的准备。虽然在一个选项卡上点击链接会影响另一个选项卡上的重新加载看起来很奇怪,但这与重新加载是否被视为“同一站点”有关。标准草案第 8.8.5 节定义规则,这些规则很复杂并且它们的实现可能因浏览器而异。
当我使用网上银行时,只要我做了任何稍微不寻常的事情,我就会退出。据我所知,我的银行不使用SameSite=Strict
,但这个例子表明,安全性高的网站非常挑剔。