What Is a JSON Web Token?

A JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a compact, URL-safe string. It's the most widely used method for stateless authentication in modern web applications and APIs.

Unlike traditional sessions that require server-side storage, JWTs are self-contained — all the information needed to verify a user's identity is encoded directly in the token.

JWT Structure: Three Parts

A JWT looks like: xxxxx.yyyyy.zzzzz — three Base64URL-encoded sections separated by dots.

1. Header

{ "alg": "HS256", // Signing algorithm "typ": "JWT" // Token type
}

2. Payload (Claims)

{ "sub": "user_123", // Subject (user ID) "name": "Jane Developer", // Custom claim "role": "admin", // Custom claim "iat": 1709251200, // Issued at "exp": 1709252100 // Expires at (15 min later)
}

Standard claims include iss (issuer), sub (subject), aud (audience), exp (expiration), iat (issued at), and jti (unique ID).

3. Signature

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret_key
)

The signature ensures the token hasn't been tampered with. Only the server holding the secret key can create valid signatures.

The JWT Authentication Flow

  1. User sends credentials (email/password) to the login endpoint
  2. Server validates credentials and creates a JWT with the user's claims
  3. Server returns the JWT to the client
  4. Client stores the JWT (typically in memory or httpOnly cookie)
  5. Client sends JWT in the Authorization: Bearer <token> header on every request
  6. Server verifies the signature and reads claims from the payload

JWT vs Session-Based Auth

FeatureJWTSessions
StorageClient-sideServer-side
ScalabilityStateless, easy to scaleRequires shared session store
RevocationHarder (need blocklist)Easy (delete from store)
Cross-domainWorks naturallyNeeds CORS config
Mobile-friendlyYesCookie issues

Access Tokens and Refresh Tokens

Best practice is to use two tokens:

  • Access token — Short-lived (5-15 minutes), sent with every API request
  • Refresh token — Long-lived (days/weeks), stored securely, used only to get new access tokens

This minimizes the damage window if an access token is compromised while avoiding frequent re-authentication.

Security Best Practices

  • Never store JWTs in localStorage — vulnerable to XSS attacks. Use httpOnly cookies or in-memory storage.
  • Keep payloads small — Don't store sensitive data; the payload is only encoded, not encrypted.
  • Always validate on the server — Never trust client-side JWT decoding for authorization.
  • Use strong secrets — At least 256 bits for HMAC; prefer RS256 (RSA) for distributed systems.
  • Set expiration — Always include exp claim. Short-lived tokens reduce risk.
  • Implement token rotation — Issue new refresh tokens on each use and invalidate old ones.

Decode and Inspect JWTs

Need to inspect a JWT's claims? Use our JWT Decoder to paste any token and see the decoded header, payload, and signature verification status instantly. For more on token security, read our JWT Token Security Guide.