You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何需在Express-Session中间件后访问session对象才能正常工作?

为什么必须访问req.session才能让Express-Session正常工作?

问题描述

TLDR:

为什么我必须在app.js的session中间件之后添加这段访问session对象的代码,才能让Express-Session正常工作?不加的话会话不会保存,也不会设置cookie。

app.use((req, res, next) => {
    req.session.init = "init";
    next();
});

编辑: 我认为这不是cookie设置的问题,因为不加这段代码时会话也不会保存,加上后会话和cookie都能正常工作。


原始问题

我正在用Express-Session将会话存储到MySQL数据库里,不知道为什么它突然不保存会话也不返回cookie了。我的Express日志如下:

express:router dispatching POST /auth/login +18s
express:router query  : /auth/login +0ms
express:router expressInit  : /auth/login +1ms
express:router session  : /auth/login +0ms
express-session no SID sent, generating session +1ms
express:router <anonymous>  : /auth/login +1ms
express:router jsonParser  : /auth/login +0ms
express:router urlencodedParser  : /auth/login +1ms
express:router trim prefix (/auth) from url /auth/login +0ms
express:router router /auth : /auth/login +1ms
express:router dispatching POST /login +0ms

但添加上述代码后,会话就能保存,也会返回cookie。我的相关代码如下:

const options = {
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_DATABASE
};

const sessionStore = new MySQLStore(options);

app.use(session({
    name: process.env.SESSION_NAME,
    secret: process.env.SESSION_SECRETS,
    store: sessionStore,
    resave: false,
    saveUninitialized: false,
  cookie: {
    secure: false,
    httpOnly: true,
    sameSite: 'strict',
    maxAge:600000
  }
}));

// 这段代码让Express-Session正常工作
app.use((req, res, next) => {
    req.session.init = "init";
    next();
});

require('./startup/headers')(app);
require('./startup/routes')(app);

app.use((error, req, res, next) => {

  const status = error.statusCode || 500;

  res.status(status).json({ message: `Error`});
});

此时的Express日志如下(注意末尾的express-session相关日志):

express:router dispatching POST /auth/login +58ms
express:router query  : /auth/login +1ms
express:router expressInit  : /auth/login +2ms
express:router session  : /auth/login +1ms
express-session no SID sent, generating session +5ms
express:router <anonymous>  : /auth/login +4ms
express:router <anonymous>  : /auth/login +0ms
express:router jsonParser  : /auth/login +3ms
express:router urlencodedParser  : /auth/login +3ms
express:router trim prefix (/auth) from url /auth/login +1ms
express:router router /auth : /auth/login +1ms
express:router dispatching POST /login +0ms

express-session saving 3FOu73E3BHGVl0Rw-KtrCOjjqcDZlxRY +31ms
express-session set-cookie session-cookie=s%3A3FOu73E3BHGVl0Rw-KtrCOjjqcDZlxRY.ucs49AVEgJFmJ1b5CeDuICqIihbDeNa294ImU4XC2lg; Path=/; Expires=Mon, 23 Jan 2023 11:29:39 GMT; HttpOnly; SameSite=Strict +9ms
express-session split response +8ms

我在文档里没找到相关说明,希望有人能解释这种行为。


原因解释

核心原因是你配置了saveUninitialized: false,这个参数的作用是拒绝保存未初始化的会话。

在Express-Session的逻辑里:

  • 当请求进来时,中间件会生成一个空的会话对象,但此时这个会话属于“未初始化”状态——没有任何属性被修改或添加。
  • 因为saveUninitialized设为false,中间件会跳过这个会话的保存流程,也不会向客户端发送Set-Cookie响应头。

你添加的req.session.init = "init"代码,本质是对会话对象做了修改,把它从“未初始化”转为“已初始化”状态。这时Express-Session就会触发会话保存逻辑,同时向客户端设置cookie。

如果你的登录接口原本就会修改req.session(比如存储用户ID、权限信息),那根本不需要这段额外代码。但如果当前登录逻辑里没有对会话做任何修改,就会出现会话不保存、不设cookie的情况。

补充:resave: false的作用是仅当会话被修改时才重新保存,和本次问题关联不大,但saveUninitialized是触发问题的关键配置。


内容的提问来源于stack exchange,提问作者NickW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 03:15:46