SkillByAIOpen interactive version →

Lesson 9 / 25

Session Lifecycle

Regenerate, time out, log out.

From login to logout

Regenerate the session ID at login and at any privilege change (such as completing MFA or entering an admin mode); otherwise an attacker who planted a known ID beforehand (session fixation) inherits the logged-in session. Apply an idle timeout (ends a session after inactivity) and an absolute timeout (ends it after a maximum lifetime, regardless of activity); shorter values suit higher-risk apps. Logout must destroy the server-side session and clear the cookie, not just hide the UI. Offer "sign out of all devices", and revoke sessions after a password change or reset. For sensitive actions (changing email, payment details), require re-authentication even inside a valid session.

Regenerate at login, destroy at logout

express-session APIs.

export function startSession(req: Request, res: Response, user: User) {
  return new Promise<void>((resolve, reject) => {
    req.session.regenerate((err) => {          // new ID, old one discarded
      if (err) return reject(err);
      req.session.userId = user.id;
      req.session.createdAt = Date.now();      // for the absolute timeout
      req.session.save((e) => (e ? reject(e) : resolve()));
    });
  });
}

const ABSOLUTE_MS = 12 * 60 * 60 * 1000;
app.use((req, res, next) => {
  if (req.session.userId && Date.now() - req.session.createdAt > ABSOLUTE_MS) {
    return req.session.destroy(() => res.status(401).end());
  }
  next();
});

app.post('/logout', (req, res) => {
  req.session.destroy(() => {
    res.clearCookie('__Host-sid', { path: '/', secure: true, httpOnly: true, sameSite: 'lax' });
    res.status(204).end();
  });
});

Idle timeout via rolling expiry

With express-session, the rolling option refreshes the cookie expiry on every response, which approximates an idle timeout. Pair it with your own absolute limit, because rolling alone lets an active session live forever.

Quick check: Why regenerate the session ID immediately after login?

  • To reset the user's password
  • To make the cookie smaller
  • To prevent session fixation using an ID set before login
  • To disable CSRF tokens
Answer

To prevent session fixation using an ID set before login — A pre-login ID could have been planted by an attacker.