Skip to main content

How to Secure an API with JWT Authentication

Issue short-lived RS256 JWT access tokens, validate them as bearer credentials with strict issuer and audience checks, add a rotating refresh token flow, and rotate signing keys via JWKS.

Difficulty
Intermediate
Duration
45 minutes
Steps
5

What and why

A JSON Web Token (JWT) is a signed, self-contained token carrying claims about a user. APIs use short-lived JWT access tokens so each request can be authenticated without a database lookup. Done right, JWTs are stateless and scalable; done wrong, they are a common source of vulnerabilities.

Prerequisites

  • A REST API you control.
  • A user store to validate credentials.
  • Understanding of the Authorization header.

Steps

1. Choose a signing algorithm

Prefer asymmetric RS256 or ES256 so verifiers only need the public key. Never accept the none algorithm, and never let the token header dictate the algorithm during verification.

2. Issue an access token on login

After verifying credentials, sign a token with short expiry:

const { SignJWT } = require('jose');
const token = await new SignJWT({ role: user.role })
  .setProtectedHeader({ alg: 'RS256', kid })
  .setSubject(user.id)
  .setIssuer('https://api.example.com')
  .setAudience('example-clients')
  .setExpirationTime('15m')
  .sign(privateKey);

3. Validate the bearer token

On each request, read Authorization: Bearer <token> and verify it:

const { payload } = await jwtVerify(token, publicKey, {
  issuer: 'https://api.example.com', audience: 'example-clients',
});
req.user = { id: payload.sub, role: payload.role };

Reject expired tokens and tokens whose iss or aud do not match.

4. Add a refresh token flow

Access tokens are short-lived. Issue a long-lived refresh token, store it server-side (so it can be revoked), and exchange it for a new access token. Rotate the refresh token on each use and detect reuse of an old one as a theft signal.

5. Rotate signing keys

Publish keys at a JWKS endpoint and include a kid in each token header so verifiers select the right key. To rotate, add a new key, sign with it, keep the old key for verification until all old tokens expire, then remove it.

Verification

  • A valid token grants access; a tampered token is rejected.
  • An expired token returns 401.
  • After rotation, tokens signed by the new key validate against the JWKS.

Next Steps

Keep access tokens short (5-15 minutes), store tokens in HttpOnly cookies for browsers, scope tokens to least privilege, and add a revocation list or token versioning for emergency invalidation.

Prerequisites

  • A REST API
  • Understanding of HTTP headers
  • A user store for credentials

Steps

  • 1
    Choose a signing algorithm
  • 2
    Issue an access token on login
  • 3
    Validate the bearer token
  • 4
    Add a refresh token flow
  • 5
    Rotate signing keys