Working with Session Management

1. Creating Server-Side Sessions

ComponentDetail
Session storeRedis, Memcached, DB
Session ID≥128-bit CSPRNG, opaque
MappingsessionId → {userId, createdAt, lastSeen, ip, ua, mfa}
TransportHttpOnly cookie
LifecycleCreate on login, rotate on privilege change, destroy on logout

Example: express-session with Redis

import session from "express-session";
import RedisStore from "connect-redis";

app.use(session({
  store: new RedisStore({ client: redis, prefix: "sess:" }),
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false,
  cookie: {
    httpOnly: true,
    secure: true,
    sameSite: "lax",
    maxAge: 1000 * 60 * 60 * 8   // 8 hours
  },
  name: "__Host-sid"
}));

2. Generating Session IDs

RequirementValue
Entropy≥64 bits (128+ recommended)
SourceOS CSPRNG (/dev/urandom, crypto.randomBytes)
EncodingBase64URL or hex
Length22+ chars (base64) or 32+ (hex)
OpacityNo embedded user data

3. Storing Session Data

StoreProsCons
In-memoryFast, simpleLost on restart, no multi-node
RedisFast, TTL, clusteredExtra infra
DBDurable, queryableSlower
Signed cookieStatelessSize limit, harder to revoke
JWTDistributed, statelessRevocation complexity

4. Setting Session Expiration

TypeTypical ValueBehavior
Idle timeout15–30 minReset on activity
Absolute timeout8–24 hrHard cap regardless of activity
Remember me14–30 daysLong-lived, MFA required to elevate
High-privilege10–15 min absoluteRe-auth required

5. Implementing Session Renewal

Example: Sliding expiration

app.use(async (req, res, next) => {
  if (req.session?.userId) {
    const idle = Date.now() - req.session.lastSeen;
    if (idle > IDLE_MS) return req.session.destroy(() => res.status(401).end());
    req.session.lastSeen = Date.now();    // extend
    await redis.expire(`sess:${req.sessionID}`, ABSOLUTE_TTL);
  }
  next();
});

6. Destroying Sessions

TriggerAction
User logoutDelete session row + clear cookie
Password changeInvalidate ALL user sessions
Role changeInvalidate ALL sessions
Admin force-logoutDelete by userId
Idle/absolute expiryTTL auto-deletes

7. Implementing Session Fixation Protection

Warning: ALWAYS regenerate the session ID after authentication to prevent attackers from pre-setting a known session ID.

Example: Session ID rotation

app.post("/login", async (req, res) => {
  const user = await verifyCredentials(req.body);
  req.session.regenerate((err) => {            // NEW session ID
    if (err) return res.status(500).end();
    req.session.userId = user.id;
    req.session.mfaPassed = false;
    res.json({ ok: true });
  });
});

8. Using Session Cookies

AttributeValueReason
HttpOnlytrueBlocks JS access (XSS)
SecuretrueHTTPS only
SameSiteLax or StrictCSRF mitigation
Path/Limit scope
Name prefix__Host-Forces Secure + path=/ + no Domain
Max-AgeSession absoluteAuto-cleanup

9. Implementing Concurrent Session Control

PolicyImplementation
Single sessionInvalidate previous on new login
Max N sessionsTrack per user, evict oldest
Device listShow user "active sessions" + revoke button
Per-device limitGroup by device fingerprint

10. Handling Session Timeout Warnings

Example: Client warning at T-60s

// poll server-time-aware expiry endpoint
setInterval(async () => {
  const { secondsLeft } = await fetch("/api/session/status").then(r => r.json());
  if (secondsLeft < 60) showModal("Session expiring. Stay signed in?");
  if (secondsLeft <= 0) location.href = "/login?expired=1";
}, 30_000);

11. Implementing Remember Me Functionality

AspectDetail
Token typeSeparate persistent cookie (not session)
StorageHashed token in DB with userId + expiry
RotationIssue new token on each use, invalidate old
Reuse detectionIf old token reused → revoke chain, alert
PrivilegeAuto-login = standard session, sensitive ops require re-auth

12. Preventing Session Hijacking

VectorMitigation
XSSHttpOnly cookie, CSP
Network sniffHTTPS + Secure cookie + HSTS
CSRFSameSite + CSRF token
FixationRotate session ID on auth
Token theftBind to IP/UA, detect anomalies → re-auth
Subdomain takeoverAvoid Domain= attribute, use __Host- prefix