JWT Token Structure Explained: Header, Payload, and Signature
JWT Token Structure Explained
Every JSON Web Token (JWT) is a compact, URL-safe string that carries claims between two parties. Understanding its internal structure is essential for any developer working with token-based security.
The Three Parts of a JWT
A JWT consists of three parts separated by dots (.):
header.payload.signature
Example:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Each part is base64url-encoded JSON. A JWT is signed, not encrypted — anyone can decode and read its contents.
Part 1: The Header
The header contains metadata about the token — the signing algorithm and token type.
| Field | Description | Example Values |
|-------|-------------|----------------|
| alg | Signing algorithm (required) | HS256, RS256, ES256 |
| typ | Token type (optional) | JWT |
| kid | Key ID (optional) | "key-1" |
{
"alg": "HS256",
"typ": "JWT"
}
The alg field tells the verifier which algorithm created the signature. An algorithm mismatch — or accepting alg: "none" — is a common JWT security vulnerability.
Part 2: The Payload
The payload contains claims about the user and metadata. Claims fall into three categories:
Registered Claims
| Claim | Full Name | Purpose |
|-------|-----------|---------|
| iss | Issuer | Who issued the token |
| sub | Subject | Identifies the user |
| aud | Audience | Intended recipient |
| exp | Expiration | Token expiry timestamp |
| nbf | Not Before | Token not valid before this time |
| iat | Issued At | Token creation timestamp |
| jti | JWT ID | Unique token identifier |
Decoded Payload Example
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622,
"iss": "https://auth.example.com"
}
Public claims are defined in the IANA registry or use collision-resistant URIs. Private claims are custom claims agreed upon between issuer and consumer.
Part 3: The Signature
The signature is created by combining the encoded header, encoded payload, and a secret key using the algorithm from the header. It serves two purposes:
- Integrity — confirms the token was not modified after signing.
- Authentication — proves the token was signed by the expected party.
HS256 Signature Creation
HMACSHA256(
base64urlEncode(header) + "." + base64urlEncode(payload),
secret
)
RS256 Signature Creation
RSASHA256(
base64urlEncode(header) + "." + base64urlEncode(payload),
privateKey
)
Base64url vs Standard Base64
| Aspect | Standard Base64 | Base64url |
|--------|-----------------|-----------|
| Char 62 | + | - |
| Char 63 | / | _ |
| Padding | = | Omitted |
This encoding ensures JWTs are safe for HTTP headers, query parameters, and URL paths without percent-encoding.
Complete JWT Creation Process
- Create the header JSON and base64url-encode it.
- Create the payload JSON and base64url-encode it.
- Concatenate with a
.separator. - Sign with the chosen algorithm and secret.
- Base64url-encode the signature.
- Concatenate all three parts with
.separators.
Security Considerations
- Never store secrets in the payload. The payload is encoded, not encrypted.
- Always validate the signature. Without verification, anyone can forge tokens.
- Check the
algheader. Rejectalg: "none"and algorithm downgrade attempts. - Set short expiration times. Use
expclaims in minutes or hours, not months.
Decode a JWT Token Online
Use the JWT decoder tool to examine any token. Paste it and instantly see the decoded header, payload, and signing algorithm. All processing happens in your browser.