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

Express会话每周在Safari Cookie中丢失Passport用户ID问题排查求助

排查与修复步骤

1. 修正express-session的配置错误

你的代码中把httpOnly和secure放在了session配置的顶层,这是错误的——这两个属性属于cookie对象的配置项,顶层配置不会生效到Cookie上。修正后的配置如下:

const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);

const max_session_ms = 365 * 24 * 60 * 60 * 1000;

const store = new MongoDBStore({
  uri: MONGO_URI,
  expires: max_session_ms,
});

app.use(
  session({
    cookie: {
      maxAge: max_session_ms,
      sameSite: "none",
      httpOnly: true,
      secure: true,
      partitioned: true,
      rolling: true
    },
    store: store,
    secret: "some secrete",
    signed: true,
    resave: true,
    saveUninitialized: false,
  })
);

2. 适配Safari智能跟踪预防(ITP)机制

Safari默认会在7天后清除被判定为“非活跃”或“跨站”的会话数据,即使Cookie过期时间设为一年:

  • 启用partitioned: true:将Cookie存储在浏览器的分区存储中,避免被ITP自动清除
  • 设置sameSite: "none":配合secure: true,确保Cookie在跨子域或第三方集成场景下正常发送
  • 开启rolling: true:用户每次发起请求时,自动更新Cookie的过期时间,同步更新MongoDB中session的expires字段,让ITP判定会话仍在活跃

3. 优化session存储配置

调整connect-mongodb-session的配置,确保session过期时间与Cookie保持一致,同时减少不必要的数据库操作:

const store = new MongoDBStore({
  uri: MONGO_URI,
  expires: max_session_ms,
  touchAfter: 24 * 3600 // 每24小时仅更新一次session的过期时间,降低数据库压力
});

4. 排查passport会话序列化逻辑

确保passport的序列化/反序列化方法在Safari环境下正常工作:

  • 在serializeUser和deserializeUser中添加日志,确认用户ID能正确写入和读取session
  • 检查是否存在Safari特有的请求头解析问题,导致passport无法读取session中的用户信息,进而清除passport字段

5. 服务器端日志定位

在服务器端添加请求日志,记录以下内容:

  • 每个请求的session ID
  • session的完整内容(重点监控passport字段的存在状态)
  • 请求是否携带了正确的session Cookie
    通过日志定位passport字段消失的具体时间点和触发请求,进一步缩小问题范围

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:09:59