express-session无法销毁会话问题咨询(附初始化及认证中间件代码)
Hey there, let's break down why your express-session + connect-mongo setup isn't destroying sessions properly. Based on the code you shared and common pitfalls with this stack, here are the key areas to investigate:
1. First, Verify Your Session Destruction Code
You didn't include your logout/destroy logic, but this is the most common culprit. Make sure you're using req.session.destroy() correctly—just deleting req.session.userId won't remove the session from the MongoDB store. Here's a proper example:
// Example logout route implementation app.get('/logout', (req, res) => { req.session.destroy((err) => { if (err) { console.error('Failed to destroy session:', err); return res.status(500).send('Could not log out'); } // Critical: Clear the session cookie from the client res.clearCookie('connect.sid'); // Use your session's "name" if you customized it res.redirect('/login'); }); });
2. Fix Your Session Configuration Settings
Your current resave: true setting can cause unexpected behavior. Connect-mongo supports the touch method (used to update session expiry without resaving the entire session), so you should set resave: false to prevent unnecessary session resaves that might interfere with destruction:
app.use(session({ secret: 'secret', resave: false, // Change this to false saveUninitialized: false, store: new MongoStore({ mongooseConnection: mongoose.connection }) }));
3. Check Connect-Mongo Version Compatibility
You're using the older connect-mongo syntax (require('connect-mongo')(session)), which might clash with newer versions of express-session. If you're running into compatibility issues, upgrade to the latest connect-mongo version and adjust your setup:
// Updated setup for modern connect-mongo versions const MongoStore = require('connect-mongo').default; app.use(session({ secret: 'secret', resave: false, saveUninitialized: false, store: MongoStore.create({ mongooseConnection: mongoose.connection // Keep using your existing mongoose connection }) }));
4. Rule Out Middleware Interference
Make sure no other middleware is modifying req.session after your authentication check. For example, if you have a caching middleware or a session refresh middleware that runs after requiresLogin, it might overwrite or re-save the session before it can be destroyed.
5. Verify the MongoDB Store Directly
Check your MongoDB database's sessions collection after attempting to destroy a session. If the session document is still present, that means req.session.destroy() isn't triggering correctly (or the store isn't communicating with MongoDB). If the document is gone but the client still acts like the session exists, you likely forgot to clear the session cookie.
6. Confirm Cookie Name Matching
If you customized the session cookie's name in your session config, ensure res.clearCookie() uses the exact same name. For example:
// If you set a custom cookie name app.use(session({ secret: 'secret', resave: false, saveUninitialized: false, name: 'my-app-session', // Custom cookie name store: new MongoStore({ mongooseConnection: mongoose.connection }) })); // Then in logout: res.clearCookie('my-app-session'); // Match the custom name
Start with checking your destruction logic first—this is where most people slip up. If that's correct, work through the configuration and version checks next.
内容的提问来源于stack exchange,提问作者AndroC

