Passport.js serializeUser/deserializeUser lacks built‑in schema‑version guard
0 reputation · 15 Nov 2024, 14:32 UTC
0 reputation · 15 Nov 2024, 14:32 UTC
Define a reliable strategy to keep existing sessions valid or safely invalidate them when the user model changes (fields added, removed, or renamed).
serializeUser returns; deserializeUser receives that opaque payload on every request.express-session store treats the session blob as opaque, so migration must happen inside deserializeUser or via custom middleware.deserializeUser to enforce version checks without per‑request overhead?34775 reputation · 15 Nov 2024, 22:55 UTC
Embed a tiny version object in the value returned by serializeUser (e.g. {id: user.id, v: '1.2.0'}). In deserializeUser parse that payload, compare the stored version with the current schema version, and either reject the session (forcing re‑login) or run a legacy mapper for backward‑compatible fields. A lightweight middleware can cache the result of that comparison per session so the version check runs only once per login.
serializeUser returns; the session store treats it as opaque JSON.deserializeUser can still parse the old format.passport.serializeUser((user, done) =>
done(null, { id: user.id, v: CURRENT_SCHEMA_VERSION }));
passport.deserializeUser(async (payload, done) => {
if (!payload || typeof payload !== 'object') return done(null, false);
if (payload.v !== CURRENT_SCHEMA_VERSION) {
// Option A: reject → force login
return done(null, false);
// Option B: migrate via legacy mapper (see note)
}
const user = await User.findById(payload.id);
done(null, user);
});
app.use((req, res, next) => {
if (req.user && !req.session._schemaValid) {
req.session._schemaValid = true; // first request after login
}
next();
});
| Approach | Pros | Cons |
|---|---|---|
| Reject on version mismatch | Simple, guarantees data integrity | Forces all users to log in again after any schema change |
| Legacy mapper + gradual migration | Keeps users logged in | Requires maintaining old field mappings; more code |
| Short rolling TTL | Limits window of stale sessions automatically | Increases login frequency; may annoy users |
CURRENT_SCHEMA_VERSION (e.g. a constant or value from package.json).express-session).v.CURRENT_SCHEMA_VERSION, restart the app, and make a request; the session should be rejected or migrated per your choice.What session store and TTL are you currently using? The recommendation for short rolling TTL vs. explicit invalidation changes based on that answer.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.