DEV Community

Cover image for Authentication Flows: Implementing Secure Session Management

Authentication Flows: Implementing Secure Session Management

Sessions are the bridge between stateless HTTP and stateful user identity. Get them wrong, and attackers hijack accounts, escalate privileges, and impersonate users. Secure sessions require careful architecture: token generation, rotation, revocation, and validation at every step.


1. Generate Cryptographically Secure Tokens

Weak tokens are predictable. Use libraries designed for token generation.

import crypto from 'crypto';
import jwt from 'jsonwebtoken';

function generateSessionToken() {
  // Cryptographically secure random token
  const randomToken = crypto.randomBytes(32).toString('hex');

  // JWT with short expiration
  const jwtToken = jwt.sign(
    { token: randomToken, type: 'session' },
    process.env.JWT_SECRET,
    { expiresIn: '1h' }
  );

  return jwtToken;
}
Enter fullscreen mode Exit fullscreen mode

2. Use Refresh Token Rotation

Access tokens are short-lived. Refresh tokens should rotate with every use, invalidating the old one.

app.post('/refresh', (req, res) => {
  const { refreshToken } = req.body;

  // Verify and decode
  const decoded = jwt.verify(refreshToken, process.env.REFRESH_SECRET);

  // Check if token is in the revocation list
  if (isRevoked(refreshToken)) {
    return res.status(403).json({ error: 'Refresh token revoked' });
  }

  // Issue new tokens
  const newAccessToken = jwt.sign({ userId: decoded.userId }, process.env.JWT_SECRET, { expiresIn: '15m' });
  const newRefreshToken = jwt.sign({ userId: decoded.userId }, process.env.REFRESH_SECRET, { expiresIn: '7d' });

  // Revoke old refresh token
  revokeToken(refreshToken);

  res.json({ accessToken: newAccessToken, refreshToken: newRefreshToken });
});
Enter fullscreen mode Exit fullscreen mode

3. Store Sessions Securely

If using server-side sessions, store them encrypted and indexed for fast lookup.

import Redis from 'ioredis';
import crypto from 'crypto';

const redis = new Redis({ password: process.env.REDIS_PASSWORD });

async function storeSession(userId, metadata) {
  const sessionId = crypto.randomUUID();
  const sessionData = JSON.stringify({
    userId,
    createdAt: Date.now(),
    ...metadata
  });

  // Store with TTL (1 hour)
  await redis.setex(`session:${sessionId}`, 3600, sessionData);

  return sessionId;
}

async function validateSession(sessionId) {
  const data = await redis.get(`session:${sessionId}`);
  if (!data) return null;
  return JSON.parse(data);
}
Enter fullscreen mode Exit fullscreen mode

4. Implement Secure HttpOnly Cookies

Store tokens in httpOnly, secure cookies that can't be accessed by JavaScript. Combine with CSRF protection.

app.post('/login', (req, res) => {
  // Authenticate user...
  const token = generateSessionToken();

  res.cookie('sessionToken', token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'Strict',
    maxAge: 1000 * 60 * 60 // 1 hour
  });

  // Include CSRF token in response body
  const csrfToken = crypto.randomBytes(32).toString('hex');
  res.json({ csrfToken });
});
Enter fullscreen mode Exit fullscreen mode

5. Detect and Respond to Session Anomalies

Log session events and alert on suspicious patterns: multiple IPs, unusual locations, or rapid token refresh.

async function validateSessionIntegrity(sessionId, req) {
  const session = await redis.get(`session:${sessionId}`);
  const current = {
    ip: req.ip,
    userAgent: req.headers['user-agent']
  };

  // Check for suspicious changes
  if (session.ip !== current.ip) {
    logger.warn(`Session hijack attempt: ${sessionId}`, { session, current });
    await redis.del(`session:${sessionId}`);
    return false;
  }

  return true;
}
Enter fullscreen mode Exit fullscreen mode

Thanks for reading! If this post was insightful for you, please share it with your team or leave a comment with your own security wins.

Sessions are the keys to your users' accounts. Protect them like you'd protect your own.

With token rotation, secure storage, and anomaly detection, session management becomes a fortress rather than a liability.

Build session security with us: kodex.studio

Top comments (0)