Introduction to JWT
A JSON Web Token (JWT) is a compact, URL-safe token format defined by RFC 7519. It encodes a set of claims — statements about a subject — as a JSON object that is digitally signed or integrity-protected using a Message Authentication Code (MAC).
JWTs are the backbone of modern, stateless authentication and authorisation patterns. They are used everywhere from OpenID Connect identity layers to API access control.
What a JWT looks like
A JWT is three dot-separated Base64url-encoded segments:
header.payload.signature
Here is a concrete example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjk5OTk5OTk5OTksInJvbGUiOiJhZG1pbiJ9.7MgJvDCvbJwNu7-KVYwCQWF9qX8y3GzD3b-lNHAhTkI
Each segment serves a distinct purpose.
The three parts
Header
The header is a JSON object that describes the cryptographic operations applied to the token. It always contains a signature or MAC algorithm (alg) and may include a token type (typ).
{
"alg": "HS256",
"typ": "JWT"
}
alg— identifies the algorithm used to sign or MAC the token (e.g. HS256, RS256, ES256). This is the only required header parameter.typ— explicitly declares the token as a JWT. While technically optional, its presence helps intermediate middleware distinguish JWTs from other token formats such as JWE or JWS.
A complete reference of supported algorithms can be found in the Algorithms section.
Payload
The payload contains the claims — statements about the subject and metadata about the token itself. Claims fall into three categories:
- Registered claims — predefined claims defined in the JWT specification that provide interoperability.
- Public claims — claim names that are registered in the IANA JSON Web Token Claims registry or use a collision-resistant name (a URI or a namespaced value).
- Private claims — custom claims agreed upon between the issuer and consumer, used for application-specific data.
Standard registered claims
The JWT specification defines seven registered claim names:
| Claim | Full name | Purpose |
|---|---|---|
iss | Issuer | Identifies who issued the JWT |
sub | Subject | Identifies the subject of the JWT |
aud | Audience | Identifies the intended recipient(s) of the JWT |
exp | Expiration | UNIX timestamp after which the token is invalid |
nbf | Not Before | UNIX timestamp before which the token is not valid |
iat | Issued At | UNIX timestamp when the token was created |
jti | JWT ID | Unique identifier for the token (prevents replay) |
A detailed explanation of each of these claims is available in the Claims reference.
Example payload
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 9999999999,
"role": "admin"
}
This payload states that the subject (sub) is user 1234567890, that the user’s display name is “John Doe”, that the token was issued at UNIX time 1516239022, and that it expires at UNIX time 9999999999. The role claim is a private claim added by the application.
Signature
The signature is the result of applying the algorithm named in the header to the following input:
HMACSHA256(
base64urlEncode(header) + "." +
base64urlEncode(payload),
secret
)
For symmetric algorithms (HS256, HS384, HS512) the same secret is used to create and verify the signature. For asymmetric algorithms (RS256, ES256, etc.) the token is signed with the private key and verified with the corresponding public key. This distinction has important security implications — see the Verification and Security sections.
When and why JWTs are used
Stateless authentication
In a traditional session-based architecture, the server stores session state in memory or a database. The client holds only a session cookie; every request requires a server-side lookup to reconstruct the session.
JWTs invert this model. The token itself carries all the information the server needs: who the user is, what they are authorised to do, and when the token expires. The server can validate the token without consulting a database. This is the defining characteristic of stateless authentication.
The trade-off is that a stateless JWT cannot be revoked before its natural expiry. If a token is compromised, the issuer cannot invalidate it unless it maintains a blocklist — which reintroduces state. For this reason, JWTs are typically short-lived (minutes to hours) and paired with refresh tokens for longer sessions.
Claims-based identity
JWTs decouple identity from a particular authentication mechanism. An OpenID Connect identity provider can issue a JWT that asserts not only “this user logged in” but also claims about their email, profile picture, and group membership. Any service that trusts the issuer’s public key can read these claims without needing to call back to the identity provider.
This makes JWTs a natural fit for:
- Single sign-on (SSO) — one identity provider issues a token consumed by many relying parties.
- Microservice architectures — a gateway validates the token once and passes the decoded payload to downstream services.
- Mobile and native applications — the token is a simple string that can be stored securely and sent with every request.
Access tokens vs ID tokens
JWTs appear in two closely related but distinct roles:
| Aspect | Access Token | ID Token |
|---|---|---|
| Purpose | Authorisation — grants access to a resource | Authentication — proves the user’s identity |
| Standard | OAuth 2.0 (no mandated format) | OpenID Connect (always a JWT) |
| Who reads it | The resource server (API) | The client application |
| Contents | Scopes, permissions, resource access | Claims about the end-user (name, email, etc.) |
An ID token is always a JWT and always signed. An access token may be a JWT but can also be an opaque string — this depends on the authorisation server’s implementation.
Security considerations
Because JWTs are self-contained, they demand careful handling:
- Always validate the signature. A token with
alg: "none"should be rejected immediately. - Use short expiration times. Long-lived tokens increase the blast radius of a leak.
- Never store sensitive data in the payload. The payload is Base64url-encoded, not encrypted — anyone holding the token can read it.
- Validate the audience (
aud) claim. Without it, a token issued for one service can be replayed against another.
The Security and Verification pages cover these topics in depth, and the Decoder tool lets you inspect any JWT client‑side.