使用connect-mongodb-session重复存储会话的问题排查求助
每次GET请求重复创建UserSessions记录问题排查
问题描述
使用connect-mongodb-session在MongoDB存储会话数据,React客户端与Express服务器通过GET/POST请求交互。目前遇到的问题:sessionid与connect.sid一致,但每次GET请求都会生成多条新的UserSessions记录。
服务器代码
require("dotenv").config(); const express = require('express'); const session = require('express-session'); const cors = require("cors"); const cookieParser = require('cookie-parser'); const mongoDbStore = require('connect-mongodb-session')(session); const store = new mongoDbStore({ uri: 'mongodb://127.0.0.1:27017/session', collection: 'UserSessions' }); store.on('error', function (error) { console.log(error); }); const app = express(); app.use(cookieParser()); const sessionConfig = { secret: process.env.SESSION_SECRET, resave: true, saveUninitialized: true, store: store, cookie: { expires: Date.now() + 1000 * 60 * 60 * 24 * 7, maxAge: 1000 * 60 * 60 * 24 * 7, httpOnly: true } } app.use(session(sessionConfig)); const corsOptions = { optionsSuccessStatus: 200, credentials: true, origin: true, } app.use(cors(corsOptions)) app.post('/api/auth', (req, res) => { console.log(req.session); res.send({ message: 'welcome to a simple HTTP cookie server' }); }); app.get('/api/users/me', (req, res) => { console.log(req.session); res.send({ name: 'Test Elek' }); }); app.listen(8080, () => console.log('The server is running port 8080...'));
客户端Fetch代码
fetch(`http://localhost:8080/api/users/me`, { method: 'GET', mode: 'cors', credentials: "include", headers: { 'Content-Type': 'application/json', }, cache: 'no-cache' }) fetch(`http://localhost:8080/api/auth`, { method: 'POST', credentials: "include", mode: 'cors', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(data), cache: 'no-cache' })
问题修复方案
1. 调整会话核心配置
resave: false:原配置resave: true会强制每次请求都重新保存会话,即便会话未修改,这是重复创建记录的核心原因。改为false后,只有会话被修改时才会触发存储更新。saveUninitialized: false:原配置会保存未初始化的会话(比如用户未登录的请求),改为false可避免无意义的会话记录。- 添加
sameSite: "lax":确保跨域场景下cookie能正确传递,避免因cookie策略导致的会话重建。
2. 修正中间件顺序
CORS中间件需要放在session和cookieParser之前,否则凭证传递可能失效,导致服务器无法识别已有会话,进而创建新会话。
3. 优化客户端请求
GET请求不需要Content-Type: application/json头(无请求体),移除后可避免不必要的请求处理逻辑。
修改后的代码
服务器代码
require("dotenv").config(); const express = require('express'); const session = require('express-session'); const cors = require("cors"); const cookieParser = require('cookie-parser'); const mongoDbStore = require('connect-mongodb-session')(session); const store = new mongoDbStore({ uri: 'mongodb://127.0.0.1:27017/session', collection: 'UserSessions' }); store.on('error', function (error) { console.log(error); }); const app = express(); // 先配置CORS const corsOptions = { optionsSuccessStatus: 200, credentials: true, origin: "http://localhost:3000" // 替换为你的React客户端实际地址 } app.use(cors(corsOptions)) app.use(cookieParser()); const sessionConfig = { secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, store: store, cookie: { expires: Date.now() + 1000 * 60 * 60 * 24 * 7, maxAge: 1000 * 60 * 60 * 24 * 7, httpOnly: true, sameSite: "lax" } } app.use(session(sessionConfig)); app.post('/api/auth', (req, res) => { console.log(req.session); res.send({ message: 'welcome to a simple HTTP cookie server' }); }); app.get('/api/users/me', (req, res) => { console.log(req.session); res.send({ name: 'Test Elek' }); }); app.listen(8080, () => console.log('The server is running port 8080...'));
客户端GET请求代码
fetch(`http://localhost:8080/api/users/me`, { method: 'GET', mode: 'cors', credentials: "include", cache: 'no-cache' })
内容的提问来源于stack exchange,提问作者Papp Zoltán
相关产品推荐
相关产品推荐

