多文件拆分路由场景下如何让express-session全局共享同一会话
问题修复方案
1. 修正session保存的异步逻辑
你之前调用req.session.save()后直接返回响应,session是异步存储的,经常还没落地就已经返回了,浏览器收到响应时还没拿到更新后的session cookie,导致后续请求认不到登录状态。
之前你把返回逻辑放到save回调里无响应,是因为没有处理异常分支,改用回调写法即可:
// 修改users.js里的login接口逻辑 else { req.session.user = req.body.username; req.session.save(err => { if (err) return res.status(500).json({status: 'failure', reason: '登录状态保存失败'}); res.status(200).json({status: 'success'}); }) }
所有手动修改session的操作(比如test路由里的views计数)都按这个写法调整,修改后等session存完再返回响应。
2. 修正前端axios配置
仅单个请求加withCredentials: true无效,需要全局开启所有请求的凭证携带:
// 你React项目里的axios全局配置 axios.defaults.withCredentials = true;
确保登录、查询feed等所有请求都会自动携带session cookie。
3. 调整session配置规避异常
- 你的session cookie名称包含空格
"the void",部分浏览器会对带空格的cookie名处理异常,改成无空格的命名比如the_void - 内存级session存储不稳定,开发环境热重载、服务重启都会清空session,而且生产环境不可用,你已经在用MongoDB,直接配
connect-mongo做持久化存储:
首先安装依赖:npm i connect-mongo
然后修改index.js里的session配置:
const MongoStore = require('connect-mongo'); // ...其他代码不变 app.use(session({ secret: process.env.SESS_SEC, resave: false, cookie: { secure: false, httpOnly: true, maxAge: 24 * 60 * 60 * 1000 }, // 加个有效期,比如1天 saveUninitialized: false, // 没修改的session不用存,减少无效存储 name: "the_void", store: MongoStore.create({ mongoUrl: "mongodb+srv://"+process.env.MDB_USER+":"+process.env.MDB_PASS+"@cluster0.ggboi.mongodb.net/TheVoid?retryWrites=true&w=majority", ttl: 24 * 60 * 60 // session有效期1天,和cookie对应 }) }))
4. 跨域配置补全
你当前的CORS配置只允许了GET、POST方法,如果有OPTIONS预检请求没处理的话也会导致cookie不生效,调整corsOptions:
var corsOptions = { origin: whitelist, methods: ['GET','POST','OPTIONS'], credentials: true, allowedHeaders: ['Content-Type'] }
所有调整完后重启服务,清空浏览器缓存重新测试即可,三个路由会共享同一份持久化存储的session,跨路由读取登录状态正常。
内容的提问来源于stack exchange,提问作者Raphael Morgan
相关产品推荐
相关产品推荐

