Articles

What Is a JWT? JSON Web Tokens, Explained

A JWT is a compact, signed token that carries JSON claims — identity and authorization without a session lookup. How it works and what to watch out for.

Chisato Chisato · · Updated · 4 min read
A digital padlock

A JSON Web Token, or JWT (pronounced “jot”), is a compact, URL-safe token that encodes a set of claims — JSON key-value pairs — and bundles them with a cryptographic signature. It’s the most common format for transmitting identity and authorization information between a client and a server without keeping any session state. The server doesn’t look anything up; it just validates the signature.

The three-part structure

A JWT is three base64url-encoded strings separated by dots: header.payload.signature.

  • Header — a JSON object naming the token type (JWT) and the signing algorithm, such as HS256 (HMAC-SHA256) or RS256 (RSA). Base64url-encoded, not encrypted.
  • Payload — the claims. These are JSON key-value pairs: standardized ones like sub (subject/user ID), exp (expiry timestamp), and iat (issued-at), plus any custom data your application adds. Also base64url-encoded, not encrypted.
  • Signature — computed over base64url(header) + "." + base64url(payload) using the algorithm and key declared in the header. This is what makes the token tamper-evident.

A compact example looks like this in transit:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiJ1c2VyXzEyMyIsImV4cCI6MTc1MDAwMDAwMH0.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The payload is readable by anyone who has the token — paste it into our free in-browser JWT decoder (or jwt.io) and you can see the claims immediately. The signature only proves the token wasn’t altered; it provides no confidentiality.

How stateless auth works

The traditional approach to authentication is a server-side session: the server stores session data, sets a cookie with a session ID, and looks up that ID on every request. JWTs flip this around.

With JWT-based auth:

  1. The user logs in. The server verifies credentials and issues a signed JWT containing the user’s ID and any relevant claims.
  2. The client stores the token (typically in memory or a secure HttpOnly cookie) and sends it with every request, usually as a Bearer token in the Authorization header.
  3. The server validates the signature and reads the claims directly from the token. No database lookup required.

This makes JWTs popular for microservices and distributed systems, where you don’t want every service to call a central session store. See what a REST API is for context on the kind of APIs JWTs typically protect.

Signing algorithms: HMAC vs RSA/EC

HS256 uses a single shared secret. Both the issuer and verifier must know it. Simple but impractical when multiple services need to verify tokens independently — every service would need the secret.

RS256 / ES256 use asymmetric key pairs. The issuer signs with a private key; verifiers check with the corresponding public key. This is better for distributed systems: publish the public key (usually as a JWKS endpoint), and any service can verify tokens without access to the private key.

One critical detail: always explicitly validate the alg claim against what your server expects. The infamous alg: none attack exploited libraries that trusted the header’s algorithm declaration and accepted unsigned tokens.

What JWTs are good at — and where they fall short

Advantages:

  • Stateless. No session store needed. Scales horizontally without sticky sessions.
  • Portable. Works across services and origins. Pairs naturally with OAuth 2.0 and OIDC for federated identity.
  • Self-contained. The claims travel with the token, reducing round trips.

Pitfalls:

  • Hard to revoke. Because the server doesn’t track sessions, a valid token stays valid until it expires. If you need immediate revocation (for logout or compromised accounts), you must maintain a blocklist — which reintroduces state.
  • Payload is readable. Never put passwords, secrets, or sensitive PII in the payload. Anyone with the token can decode it.
  • Expiry is critical. Set a short exp — minutes to an hour is typical for access tokens. Pair with refresh tokens for longer sessions so short-lived access tokens can be replaced without re-prompting the user.
  • Algorithm confusion. Validate the alg header server-side. Reject none and unexpected algorithms.
  • Transport security. A JWT is a bearer token: whoever holds it can use it. Always transmit over HTTPS.

JWTs vs server sessions

Server sessionsJWTs
State locationServer-side storeEncoded in the token
RevocationEasy (delete the record)Requires a blocklist
ScalabilityRequires shared session storeStateless, scales naturally
VisibilityOpaque ID; data stays server-sidePayload readable by token holder
Best forTraditional web appsAPIs, microservices, SPAs

Where JWTs fit in the auth landscape

JWTs are a token format, not an auth protocol. They’re most commonly issued as part of OAuth 2.0 flows or OpenID Connect — where an identity provider authenticates the user and hands back a signed JWT (an ID token or access token). Newer alternatives like passkeys focus on the authentication step, replacing passwords at the front door; they still often result in a JWT being issued to the application afterward.

If you’re building an auth system, use a well-audited library or identity provider rather than rolling JWT handling yourself. The format is simple; the edge cases are not.

The takeaway

A JWT is a base64url-encoded header, payload, and signature joined by dots. The signature makes it tamper-evident; the payload is always readable. For stateless APIs it’s a practical default — just keep tokens short-lived, validate the algorithm and expiry on every request, never put secrets in the payload, and pair access tokens with refresh tokens for sessions that outlast a few minutes.

Chisato Chisato · · 5 min read

What Is Session Fixation?

Session fixation tricks a victim into using an attacker-known session ID, so logging in hands the attacker an authenticated session too.

#Security #Authentication #Web Development
Chisato Chisato · · 4 min read

The OAuth PKCE Flow Explained

PKCE hardens the OAuth authorization code flow against interception, and is now recommended for every client type, not just mobile and single-page apps.

#Security #Authentication #Web Development