Lesson 28 +10 XP

JSON Web Tokens (JWT) Authentication

Stateless Authentication with JWT

JSON Web Tokens (JWT) allow authenticating requests statelessly without storing session IDs in database memory.

Structure of a JWT

A JWT consists of 3 dot-separated base64url encoded parts:

  1. Header: Cryptographic algorithm (HS256) and token type (JWT).
  2. Payload: Token claims (userId, role, expiration exp).
  3. Signature: Cryptographic signature calculated using secret key.
const jwt = require("jsonwebtoken");
const JWT_SECRET = process.env.JWT_SECRET || "super-secret-key-123";

// 1. Sign JWT upon successful login
function generateToken(user) {
  return jwt.sign(
    { userId: user.id, role: user.role },
    JWT_SECRET,
    { expiresIn: "1h" }
  );
}

// 2. JWT Verification Middleware
function authenticateJWT(req, res, next) {
  const authHeader = req.headers.authorization;

  if (!authHeader || !authHeader.startsWith("Bearer ")) {
    return res.status(401).json({ error: "Access denied. No token provided." });
  }

  const token = authHeader.split(" ")[1];

  try {
    const decoded = jwt.verify(token, JWT_SECRET);
    req.user = decoded; // Attach user payload to request
    next();
  } catch (err) {
    return res.status(403).json({ error: "Invalid or expired token." });
  }
}

TL;DR

  • Clients store JWT and send it in Authorization: Bearer <token> request header.
  • jwt.sign(payload, secret, { expiresIn }) creates token.
  • jwt.verify(token, secret) validates signature and expiration.