部署到Heroku后Express session不持久,设置sameSite:none无set-cookie响应头
问题修复方案
核心根因
Heroku 采用反向代理架构处理用户请求,你的 Node 服务实际运行在代理层之后,默认 Express 不信任代理传递的请求协议标识,即使客户端走 HTTPS 访问 Heroku 入口,Node 服务拿到的还是 HTTP 请求标识,因此会判定当前连接不符合 secure: true 的 cookie 下发要求,直接忽略了 set-cookie 逻辑。
具体修改步骤
- 新增代理信任配置,放在所有中间件最前面
给 Express 开启代理信任,让它可以正确识别代理层传递的 HTTPS 请求标识
app.set('trust proxy', 1);- 新增代理信任配置,放在所有中间件最前面
- 调整中间件加载顺序
express-session依赖cookieParser处理 Cookie,必须把cookieParser的调用放在session中间件之前,你当前的代码顺序是反的。
- 调整中间件加载顺序
- (可选优化)调整 session 配置的非必填参数
官方推荐resave和saveUninitialized设为 false,减少无效的 session 存储操作,不影响核心逻辑。
- (可选优化)调整 session 配置的非必填参数
修改后完整参考代码
// 代理信任配置放在最顶部 app.set('trust proxy', 1); // Middlewares app.use(express.json()); app.use(cookieParser("secret")); // 移到session前面 app.use( cors({ origin: "https://authclient.netlify.app", credentials: true, }) ); app.use( session({ secret: "secret", resave: false, // 推荐修改 saveUninitialized: false, // 推荐修改 cookie: { sameSite: "none", secure: true, }, store: MongoStore.create({ mongoUrl: dbURI }), }) ); app.use(passport.initialize()); app.use(passport.session()); require("./passportConfig")(passport);
额外检查项
确认前端发请求时开启了凭证携带配置:
- 如果用 Axios,要设置
withCredentials: true - 如果用原生 Fetch,要设置
credentials: 'include'
内容的提问来源于stack exchange,提问作者Rohit Dhas
相关产品推荐
相关产品推荐

