JWT Explained: Header, Payload and Signature
JWT Explained: Header, Payload and Signature
JSON Web Tokens (JWTs) are everywhere: login systems, API authentication, microservice communication, and single sign-on. Yet most developers use JWTs without understanding how they actually work — leading to security vulnerabilities, broken authentication, and debugging nightmares.
This article explains the JWT structure, shows exactly how verification works, walks through synthetic examples you can decode yourself, and covers the most common mistakes developers make with JWTs.
What Is a JWT?
A JSON Web Token (RFC 7519) is a compact, self-contained token that represents claims between two parties. Its most common use is authentication: the server issues a JWT after login, and the client includes it in every subsequent request.
A complete JWT looks like this:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiMTIzNDUiLCJuYW1lIjoiQWxpY2UiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3NTYzMDA4MDAsImV4cCI6MTc1NjMwNDQwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Split on "." → 3 parts:
Part 1 (Header): eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Part 2 (Payload): eyJ1c2VyX2lkIjoiMTIzNDUiLCJuYW1lIjoiQWxpY2Ui...
Part 3 (Signature): SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Decode any JWT: Use the JWT Decoder to paste this token and see the decoded header, payload, and signature instantly. The JWT Structure Analyzer breaks down every field.
Part 1: The Header
The header specifies the signing algorithm and token type:
Base64URL decode the header:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
↓ decode
{
"alg": "HS256", ← Signing algorithm (HMAC-SHA256)
"typ": "JWT" ← Token type
}
| Field | Required | Description |
|---|---|---|
| alg | Yes | Signing algorithm: HS256, HS384, HS512, RS256, ES256 |
| typ | Yes | Token type: always "JWT" |
| kid | No | Key ID — identifies which key was used to sign |
Try it: Use the JWT Header Decoder to decode the header of any JWT token.
Part 2: The Payload
The payload contains the claims — statements about the user and the token:
Base64URL decode the payload:
eyJ1c2VyX2lkIjoiMTIzNDUiLCJuYW1lIjoiQWxpY2UiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3NTYzMDA4MDAsImV4cCI6MTc1NjMwNDQwMH0
↓ decode
{
"user_id": "12345",
"name": "Alice",
"role": "admin",
"iat": 1756300800,
"exp": 1756304400
}
Standard Claims (Registered)
| Claim | Name | Example | Description |
|---|---|---|---|
| iss | Issuer | "auth.bestwordz.com" | Who created the token |
| sub | Subject | "12345" | Who the token is about |
| aud | Audience | "api.bestwordz.com" | Who should accept this token |
| exp | Expiration | 1756304400 | When the token expires (Unix timestamp) |
| iat | Issued At | 1756300800 | When the token was created |
| nbf | Not Before | 1756300800 | When the token becomes valid |
Decode claims: Use the JWT Payload Decoder to see all claims. The JWT Claims Viewer provides a detailed breakdown. Convert timestamps with the JWT Timestamp Converter.
Custom Claims
You can add any custom claims you need:
{
"user_id": "12345",
"name": "Alice",
"email": "alice@example.com", ← custom
"role": "admin", ← custom
"permissions": ["read", "write"], ← custom
"org_id": "org_42", ← custom
"iat": 1756300800,
"exp": 1756304400
}
Part 3: The Signature
The signature is the security mechanism. It proves two things:
- Integrity: The token hasn't been modified since it was issued
- Authenticity: It was created by someone who knows the secret key
How the signature is computed:
For HMAC (HS256, HS384, HS512):
signature = HMAC-SHA256(
base64url(header) + "." + base64url(payload),
secret_key
)
For RSA (RS256, RS384, RS512):
signature = RSA-SHA256(
base64url(header) + "." + base64url(payload),
private_key
)
For ECDSA (ES256, ES384, ES512):
signature = ECDSA-SHA256(
base64url(header) + "." + base64url(payload),
private_key
)
Try HMAC: Use the HMAC-SHA256 Generator to compute HMAC signatures. See how the HMAC Demonstrator works step by step. For RSA signatures, try the RSA-PSS Sign tool.
How Verification Works
When a server receives a JWT, it follows this verification process:
Verification pseudocode:
function verifyJWT(token, secret_key):
# 1. Split the token
parts = token.split(".")
if parts.length != 3:
return REJECT # Malformed token
# 2. Recompute the expected signature
signing_input = parts[0] + "." + parts[1]
expected_sig = HMAC_SHA256(signing_input, secret_key)
# 3. Compare signatures (constant-time comparison!)
actual_sig = base64url_decode(parts[2])
if not constant_time_compare(expected_sig, actual_sig):
return REJECT # Invalid signature
# 4. Decode and validate claims
payload = base64url_decode(parts[1])
if payload.exp < current_time():
return REJECT # Token expired
if payload.iss != expected_issuer:
return REJECT # Wrong issuer
# 5. All checks passed
return ACCEPT
JWT Algorithm Comparison
| Algorithm | Type | Key | Use Case |
|---|---|---|---|
| HS256 | Symmetric | Shared secret | Same server issues and verifies |
| RS256 | Asymmetric | RSA private/public pair | Multiple services verify |
| ES256 | Asymmetric | ECDSA private/public pair | Smaller signatures, mobile |
| none | None | No key | NEVER use in production |
Common JWT Mistakes
❌ Mistake 1: Putting Secrets in the Payload
Dangerous:
{"user": "alice", "password": "secret123", "ssn": "123-45-6789"}
The payload is only Base64URL-encoded. Anyone can decode it. JWTs provide integrity, not confidentiality.
❌ Mistake 2: Not Validating the Algorithm
Dangerous:
An attacker changes the header to {"alg": "none"}. If the server doesn't validate the algorithm, it accepts the token without any signature check.
Fix: Always verify the algorithm matches what you expect before checking the signature.
❌ Mistake 3: Using a Weak Secret
Dangerous:
secret = "mysecret"
Short or predictable secrets can be brute-forced. Use at least 256 bits (32 bytes) of cryptographically random data.
❌ Mistake 4: Not Checking Expiration
Dangerous:
If the server never checks the exp claim, a stolen token works forever.
Fix: Always validate exp, iat, and nbf. Use short expiration times (15 min for access tokens).
❌ Mistake 5: Using JWTs as Session Tokens
Risky:
JWTs cannot be revoked. Once issued, a valid JWT works until it expires. If a user logs out or their account is compromised, you cannot invalidate their existing JWTs.
Fix: Use short-lived access tokens + refresh token rotation, or maintain a token blocklist.
HS256 vs RS256 vs ES256
| Property | HS256 | RS256 | ES256 |
|---|---|---|---|
| Key type | Shared secret | RSA key pair | ECDSA key pair |
| Speed | Fastest | Slowest | Fast |
| Signature size | 32 bytes | 256 bytes | 64 bytes |
| Key distribution | Hard (shared) | Easy (public key) | Easy (public key) |
| Best for | Single server | Microservices | Mobile, IoT |
Generate keys: Create RSA keys with the RSA Key Pair Generator. Create ECDSA keys with the ECDSA Key Generator. Sign with RSA-PSS Sign and verify with RSA-PSS Verify.
JWT Best Practices Checklist
- ✅ Always validate the signature before trusting any claims
- ✅ Validate the algorithm in the header matches your expected algorithm
- ✅ Check the
expclaim — reject expired tokens - ✅ Check
issandaudclaims - ✅ Use short expiration (15 min for access tokens)
- ✅ Use at least 256-bit secrets for HS256
- ✅ Never put secrets or sensitive data in the payload
- ✅ Use RS256 or ES256 when multiple services need to verify
- ✅ Implement token revocation for logout/compromise
- ✅ Use HTTPS to prevent token interception
- ✅ Store tokens in httpOnly cookies or secure storage, not localStorage
Try It Yourself: BestWordz JWT Tools
Decode & Inspect
- JWT Decoder — Decode any JWT and see header, payload, and signature
- JWT Header Decoder — Decode just the header
- JWT Payload Decoder — Decode just the payload
- JWT Claims Viewer — Detailed claims breakdown
- JWT Structure Analyzer — Full structural analysis
- JWT Expiration Checker — Check if a token is expired
- JWT Timestamp Converter — Convert Unix timestamps in JWTs
Sign & Verify
- HMAC-SHA256 Generator — Compute HMAC signatures (HS256)
- HMAC-SHA512 Generator — Compute HMAC signatures (HS512)
- HMAC Demonstrator — See HMAC step by step
- RSA-PSS Sign — Create RSA signatures (RS256)
- RSA-PSS Verify — Verify RSA signatures
- ECDSA Sign — Create ECDSA signatures (ES256)
- ECDSA Verify — Verify ECDSA signatures
Key Generation
- RSA Key Pair Generator — Generate RSA keys for RS256
- ECDSA Key Generator — Generate ECDSA keys for ES256
Conclusion
JWTs are a powerful authentication mechanism, but they're only as secure as their implementation. The three-part structure — header, payload, signature — is simple to understand but easy to misuse.
The most critical thing to remember: JWTs are signed, not encrypted. The payload is readable by anyone. The signature only proves integrity and authenticity. Use JWTs for stateless authentication where the claims are not sensitive, and always validate every field before trusting the token.
Related BestWordz Resources
- Hashing vs Encryption vs Encoding — Why HMAC is hashing, not encryption
- How HTTPS and TLS Actually Work — TLS protects JWTs in transit
- Hashing vs Encryption vs Encoding Demo — Interactive comparison
- AI Security Risks — Securing AI agents with JWT authentication
- Protecting API Keys and Secrets — Why JWTs aren't for secret storage
💬 Discuss this topic
Have questions or insights about JWT Explained: Header, Payload and Signature? Join the BestWordz Community.
📚 Related Articles
OAuth 2.0 Explained for Beginners
Key Takeaway --> OAuth 2.0 is an authorization framework — it lets users grant third-party apps li…
CybersecurityHashing vs Encryption vs Encoding: What's the Difference?
Key Takeaway --> Hashing verifies integrity and stores passwords safely. Encryption keeps data con…
CybersecurityThe Shift: From Implementation to Judgment
Key Takeaway --> 🎯 Key Takeaway AI agents change how you implement software — not what you need t…
CybersecurityCross-Site Scripting Explained for Web Developers
KEY TAKEAWAY Cross-Site Scripting (XSS) happens when untrusted user input is included in web page…
CybersecurityHow HTTPS and TLS Actually Work
Key Takeaway --> HTTPS is HTTP running over TLS. The TLS handshake performs three critical functio…
CybersecurityAPI Authentication Methods Compared
Key Takeaway --> There is no single "best" API authentication method. API keys are simple but weak…
🔧 Related Tools
JWT Decoder
Decode and inspect JSON Web Tokens (JWT) locally.
Try it now →JWT Header Decoder
Decode the header segment of a JSON Web Token.
Try it now →HMAC-SHA256 Generator
Generate an HMAC-SHA256 signature from a key and message, entirely in your browser.
Try it now →HMAC-SHA512 Generator
Generate an HMAC-SHA512 signature from a key and message, entirely in your browser.
Try it now →💬 Discuss on BestWordz Community
Join the conversation about RAG, AI Agents, Cybersecurity on the BestWordz Community forum.
Visit Forum →