How JWT works
A JSON Web Token is a compact, URL-safe way to carry claims between parties, protected by a signature. This guide walks through the structure, the lifecycle and where JWTs fit in OAuth 2.0 and OpenID Connect.
The three parts
A signed JWT (RFC 7519 on top of RFC 7515) is three Base64URL strings separated by dots:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 header
.eyJzdWIiOiJ1c2VyLTEyMyIsImV4cCI6MTc5MDYwNjQwMH0 payload
.3Yp5hsYlTb2iZ5NDOiR6kMEUQxxuN8gCzTpHwjrcvJI signature- Header — JSON describing the token:
{"alg":"HS256","typ":"JWT"}. It may also carry akididentifying the signing key. - Payload — JSON claims: who the token is about (
sub), who issued it (iss), who it is for (aud), when it expires (exp) and any application data. - Signature — computed over
header.payloadwith the algorithm in the header. See JWT signatures explained.
Base64URL encoding
Base64URL is Base64 with - and _ instead of + and /, and without = padding, so tokens can travel in URLs and headers unescaped. It is an encoding, not encryption: atob is all it takes to read a payload. Never put secrets in a JWT payload unless the whole token is encrypted as a JWE.
Lifecycle of a token
- A user or service authenticates with an issuer (an authorization server or your login endpoint).
- The issuer builds the claims, sets a short
exp, and signs them with its private key or shared secret. - The client stores the token and sends it with each request:
Authorization: Bearer eyJ…. - The API verifies the signature with a key it trusts, pinning the algorithm, then validates exp, nbf, iss and aud.
- If everything checks out, the API authorizes the request using the claims — no session lookup needed.
- Near expiry, the client uses a refresh token to obtain a new access token.
JWTs in OAuth 2.0 and OpenID Connect
OAuth 2.0 access tokens are often JWTs (profiled by RFC 9068 with typ: at+jwt). OpenID Connect ID tokens are always JWTs: they tell the client who logged in, and must be validated against the client ID as audience and the nonce the client sent. The issuer publishes its public keys as a JWKS, found through /.well-known/openid-configuration.
Trade-offs
- Stateless verification scales well, but a JWT can't be revoked before it expires without extra state (deny-lists, short lifetimes).
- Self-contained claims avoid lookups, but become stale when roles change.
- Size grows with every claim and travels with every request; keep payloads lean.
See every part of a real token — header, claims, timeline and signature — in the decoder.
Decode a JWTWant to build one yourself? Create a signed test token on JWTEncoder.com.