我已经和这个问题斗争了好几个小时了,但我无法让它工作。我正在创建一个 React 应用程序(vite),对于后端,我使用 NodeJS 和 Express。我还在后端使用快速会话来处理会话。由于某种原因,谷歌浏览器中未设置会话 cookie。它在 Safari 和 Firefox 中运行良好。我已经尝试了从其他类似问题的答案中找到的所有内容,但到目前为止没有一个有效。我可能会遗漏一些东西,但无法弄清楚是什么。这是我的后端代码。需要注意的是,我目前仅处于本地主机和开发模式。我还没有在生产中尝试过这个,因为应用程序还没有准备好。
//app.js (backend)
const express = require('express');
const cookieParser = require('cookie-parser');
const cors = require('cors');
const dotenv = require('dotenv');
const { connect, MONGO_URI } = require('./db');
const session = require('express-session');
const MongoStore = require('connect-mongo');
connect();
dotenv.config();
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
app.set('trust proxy', 1);
const FRONTEND_URL = process.env.FRONTEND_URL.split(',') || [
'http://localhost:5533/',
];
app.use(
cors({
origin: FRONTEND_URL,
credentials: true,
})
);
app.options('*', cors());
const port = process.env.PORT || 8080;
app.use(
session({
secret: process.env.SESSION_SECRET || 'MySecret$',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 600000,
sameSite: 'none',
secure: false,
httpOnly: true,
},
store: MongoStore.create({
mongoUrl: MONGO_URI,
}),
})
);
app.use('/api', require('./routes/index.routes'));
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
在我的 React 应用程序中,当使用 Fetch 调用 API 时,我正在传递凭据:“include”选项。
const response = await fetch(API_URL + '/visitor', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({}),
credentials: 'include',
});
关于为什么 Chrome 不设置会话 cookie 有什么想法吗?任何帮助将不胜感激。
正如我提到的,Firefox 甚至 Safari 都可以正常工作,会话 cookie 已正确设置。
要在 Chrome 中启用 SameSite:'None' 属性,您需要在开发环境中通过 HTTPS 为您的应用程序提供服务。您可以使用 mkcert 等工具来设置本地开发 SSL 证书。如果您打算采用这种方法,则设置 secure: true 。或者您可以有条件地为开发环境添加 SameSite=Lax 。或者只是在开发过程中一起删除这条线。
同样在开发模式下,当您的应用程序没有在处理 HTTPS 终止的反向代理后面运行时,您不需要设置 app.set('trust proxy', 1)。尝试这样的事情,
process.env.NODE_ENV === 'production' && app.set('trust proxy', 1)