Duplicate session cookie when changing configuration
I noticed that changing the configuration in production/deployed mode of express-session cookies can lead to duplicate connect.sid cookie stored in the browser with the old and the new configuration - which can be very problematic to retrieve the right session afterwards.
New configuration :
store: redisStore,
secret: envConfig.OTHER_TOKEN_SECRET,
resave: false,
saveUninitialized: true,
cookie: {
secure: envConfig.ENV === 'local' ? false : true,
httpOnly: true,
sameSite: envConfig.ENV === 'local' ? 'lax' : 'none',
maxAge: 60 * 60 * 1 * 1000, // 1 hour
partitioned: envConfig.ENV === 'local' ? false : true,
},
Old configuration :
store: redisStore,
secret: envConfig.OTHER_TOKEN_SECRET,
resave: false,
saveUninitialized: true,
cookie: {
secure: true,
httpOnly: true,
sameSite: envConfig.ENV === 'local' ? 'lax' : 'none',
},
To fix this, I had no choice but to change the name of the session cookie stored in the browser.
Thank you @AntoineAwaida for reporting this.
I agree. It can create session ambiguity in cases when duplicate cookies are sent to the server.
However, its not a bug. When you change cookie attributes (e.g., secure, domain, or path) or rename the cookie, browsers treat the new configuration as a separate cookie while still retaining the old one until it expires. This is standard cookie behavior, not specific to express-session.
In order address your issue, you can name your cookies,
app.use(
session({
name: 'connect.sid.v2', // New cookie name
secret: 'your-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
sameSite: 'strict',
},
})
);
And you can do something like this to migrate,
app.use((req, res, next) => {
const oldCookie = req.cookies['connect.sid'];
const newCookie = req.cookies['connect.sid.v2'];
if (oldCookie && !newCookie) {
// Attempt to migrate the old session
req.sessionStore.get(oldCookie, (err, session) => {
if (err || !session) {
// Old session doesn't exist or failed to load
return next();
}
// Save the old session under the new cookie name
req.sessionStore.set(newCookie, session, (err) => {
if (err) console.error('Failed to migrate session:', err);
// Clear the old cookie and proceed
res.clearCookie('connect.sid');
next();
});
});
} else {
next();
}
});
What I can agree on is, this is rather a feature request or idea. Perhaps we need something like,
- Migration support for cookie configuration change
- Cookie conflict resolution support
For the meantime, I am going to label this as a idea and let's see how the discussion continues. Personally, I am 👍 for adding a migration support or something like that.
cc: @expressjs/session-collaborators