JWT Tokens Explained: Header, Payload & Signature
JSON Web Tokens (JWTs) are the backbone of modern web authentication. If you have ever logged into a single-page application, used an OAuth-protected API, or worked with microservices, you have almost certainly handled JWTs. Despite their ubiquity, JWTs are frequently misunderstood — leading to security vulnerabilities that could have been avoided with a solid understanding of how they work.
Want to inspect a JWT right now? Paste it into our JWT Decoder to instantly see the header, payload, and signature — all decoded in your browser.
What Is a JWT?
A JSON Web Token is a compact, URL-safe string that represents claims (pieces of information) between two parties. It is defined in RFC 7519 and is pronounced "jot." JWTs are self-contained: the token itself carries all the information needed to verify the user's identity and permissions, without requiring a database lookup on every request.
A JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Three parts separated by dots. Each part has a specific purpose. Let us break them down.
The Three Parts of a JWT
1. Header
The header is a JSON object that describes the token type and the signing algorithm. It is Base64url-encoded to form the first part of the token:
// Encoded:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
// Decoded:
{
"alg": "HS256",
"typ": "JWT"
}
- alg — the signing algorithm. Common values:
HS256(HMAC-SHA256),RS256(RSA-SHA256),ES256(ECDSA-SHA256),none(unsigned, dangerous). - typ — the token type, always
"JWT".
2. Payload (Claims)
The payload contains the claims — statements about the user and additional metadata. It is also Base64url-encoded:
// Encoded:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0
// Decoded:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true,
"iat": 1516239022
}
Claims fall into three categories:
Registered Claims (defined in RFC 7519, all optional but recommended):
- iss (issuer) — who created the token (e.g.,
"auth.example.com") - sub (subject) — who the token is about (usually the user ID)
- aud (audience) — who the token is intended for (e.g.,
"api.example.com") - exp (expiration) — Unix timestamp when the token expires
- iat (issued at) — Unix timestamp when the token was created
- nbf (not before) — token is invalid before this time
- jti (JWT ID) — unique identifier for the token (useful for revocation)
Public Claims are defined in the IANA JSON Web Token Registry to avoid naming collisions between organizations. Examples include email, name, and picture.
Private Claims are custom claims agreed upon between the parties, like admin, role, or department.
3. Signature
The signature is what makes JWTs trustworthy. It ensures the token has not been tampered with since it was created. The signature is computed by taking the encoded header, encoded payload, a secret key, and the algorithm specified in the header:
// For HMAC-SHA256:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
// For RSA-SHA256:
RSASHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
privateKey
)
When a server receives a JWT, it recalculates the signature using its secret key and compares it with the signature in the token. If they do not match, the token has been altered and is rejected.
HMAC vs. RSA Signing
Choosing the right algorithm depends on your architecture:
- HMAC (HS256, HS384, HS512) — symmetric algorithm. The same secret key is used to both sign and verify the token. Simple and fast. Best for monolithic applications where only one server creates and validates tokens.
- RSA (RS256, RS384, RS512) — asymmetric algorithm. A private key signs the token, and a public key verifies it. The public key can be shared freely. Best for microservices and distributed systems where many services need to verify tokens but only the auth server should create them.
- ECDSA (ES256, ES384, ES512) — asymmetric like RSA but with smaller key sizes and faster signature generation. Increasingly popular for mobile and IoT applications.
When to Use JWTs
Authentication
The most common use case. After a user logs in, the server issues a JWT. The client includes the token in the Authorization header of subsequent requests:
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
The server verifies the signature and extracts the user's identity from the payload — no database query needed.
Authorization
JWTs can carry role and permission claims. A token with "role": "admin" lets API endpoints check permissions directly from the token without querying a permissions database on every request.
Information Exchange
Because JWTs are signed, the receiver can trust that the content has not been modified. This makes them useful for securely passing information between services in a microservices architecture.
Security Best Practices
JWTs are powerful but can be dangerous when misused. Follow these rules:
- Always verify the signature — never trust a JWT without validating it. Use a well-tested library like
jsonwebtoken(Node.js),PyJWT(Python), orjava-jwt(Java). - Always check the
expclaim — reject expired tokens. Clock skew of a few seconds is normal; most libraries allow a configurable leeway. - Validate
issandaud— ensure the token was issued by your auth server and intended for your application. This prevents token confusion attacks across different services. - Never accept
"alg": "none"— thenonealgorithm means no signature. Attackers modify the header to"alg": "none"and strip the signature. Your library must reject unsigned tokens. - Keep tokens short-lived — access tokens should expire in 5-15 minutes. Use refresh tokens (stored securely, typically in HttpOnly cookies) for obtaining new access tokens.
- Do not store sensitive data in the payload — the payload is not encrypted, just encoded. Anyone can decode it. Never include passwords, credit card numbers, or secrets.
- Use HTTPS — JWTs transmitted over plain HTTP can be intercepted. Always use TLS.
- Use strong secrets — for HMAC signing, use a cryptographically random secret of at least 256 bits. A short or predictable secret can be brute-forced.
Common Pitfalls
- Storing too much in the token — every claim increases the token size, which is sent with every request. Keep payloads lean. Put detailed user data in a cache or database, not the JWT.
- Not implementing token revocation — JWTs are valid until they expire. If a user logs out or an account is compromised, you cannot "invalidate" a JWT unless you maintain a server-side blocklist or use very short expiration times.
- Algorithm confusion attacks — if your server accepts multiple algorithms, an attacker might switch from RSA to HMAC and use the public key as the HMAC secret. Always whitelist the expected algorithm on the server side.
- Using JWTs as session storage — JWTs are not a replacement for server-side sessions in all cases. If you need instant revocation, session data that changes frequently, or tokens that exceed 8KB, traditional sessions may be simpler and safer.
Decode Your JWTs Now
Our JWT Decoder instantly splits any token into its header, payload, and signature. See the decoded JSON, verify the structure, and check the expiration — all in your browser. For related tasks, try the Base64 Encoder/Decoder, Hash Generator, or JSON Formatter.