Guide · Developer security
JWT Playground Tutorial: Hands-On Learning
Master JSON Web Tokens through interactive examples. Learn to create, decode, and verify JWTs step-by-step with real-world scenarios and security best practices.
What You'll Learn
JWT Anatomy
- Header structure and algorithms
- Payload claims and data
- Signature verification process
- Base64URL encoding explained
Practical Skills
- Create and sign JWTs
- Decode and validate tokens
- Handle expiration times
- Debug common issues
Security Focus
- Algorithm security (HS256 vs RS256)
- Secret management
- Attack prevention
- Production deployment
JWT Basics: Understanding the Structure
Anatomy of a JWT
A JWT consists of three parts separated by dots (.). Let's break down each component:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cHeader
Contains algorithm and token type
{
"alg": "HS256",
"typ": "JWT"
}Payload
Contains the claims/data
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}Signature
Verifies token integrity
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)Interactive Exercise 1: Creating Your First JWT
Goal: Create a Basic JWT. Let's create a JWT for a user authentication scenario. You'll learn how each component contributes to the final token.
Step 1: Define the Header
The header specifies the algorithm used for signing. HS256 (HMAC with SHA-256) is common for simple use cases.
{
"alg": "HS256",
"typ": "JWT"
}Base64URL Encoded: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Step 2: Create the Payload
The payload contains claims about the user and session. Include essential information but keep it lean.
{
"sub": "user123", // Subject (user ID)
"name": "Alice Johnson", // Custom claim
"role": "user", // User role
"iat": 1640995200, // Issued at (timestamp)
"exp": 1641001200 // Expires at (timestamp)
}Base64URL Encoded: eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIEpvaG5zb24iLCJyb2xlIjoidXNlciIsImlhdCI6MTY0MDk5NTIwMCwiZXhwIjoxNjQxMDAxMjAwfQ
- Never include passwords or sensitive data in the payload
- JWTs are encoded, not encrypted (readable with base64 decode)
- Use short expiration times (15-60 minutes) for access tokens
Step 3: Generate the Signature
The signature ensures the token hasn't been tampered with. It's created using the header, payload, and a secret key.
signature = HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
"your-secret-key"
)Example Secret: mySecureSigningKey2024!
Resulting Signature: k8GTeGOJhBtC1esXPRYGHQMnM2s6i4DYvAkGNDqHlJM
Complete JWT Token
Combining all three parts with dots creates your final JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyMTIzIiwibmFtZSI6IkFsaWNlIEpvaG5zb24iLCJyb2xlIjoidXNlciIsImlhdCI6MTY0MDk5NTIwMCwiZXhwIjoxNjQxMDAxMjAwfQ.k8GTeGOJhBtC1esXPRYGHQMnM2s6i4DYvAkGNDqHlJMInteractive Exercise 2: Decoding and Validating JWTs
Goal: Understand JWT Verification. Learn how to decode JWT components and verify their integrity. This is crucial for secure authentication.
Sample JWT to Analyze
Let's decode this JWT step by step to understand its contents:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyNDU2IiwibmFtZSI6IkJvYiBTbWl0aCIsImFkbWluIjp0cnVlLCJpYXQiOjE2NDA5OTUyMDAsImV4cCI6MTY0MTAwMTIwMH0.t6tH7SqE1X-6SxlsEoaVQFhpvEp7WLLhRqXXXjQfbTc1. Decode Header
Encoded: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
{
"alg": "HS256",
"typ": "JWT"
}2. Decode Payload
Encoded: eyJzdWIiOiJ1c2VyNDU2Ii...
{
"sub": "user456",
"name": "Bob Smith",
"admin": true,
"iat": 1640995200,
"exp": 1641001200
}3. Verify Signature
Signature: t6tH7SqE1X-6SxlsEoaVQF...
Verification: valid with secret "mySecretKey123"
Validation Checklist
When receiving a JWT, perform these validation steps:
Structure Validation
- Three parts separated by dots
- Valid Base64URL encoding
- Header contains required fields
- Payload has valid JSON structure
Security Validation
- Signature verification passes
- Token hasn't expired (exp claim)
- Token is not used before valid time (nbf)
- Issuer is trusted (iss claim)
- Trusting tokens without signature verification
- Not checking expiration times
- Accepting tokens with "none" algorithm
- Using weak or default secrets
Real-World Scenarios
Scenario 1: User Login System
Building a secure login system where JWTs are issued after successful authentication.
Implementation Steps:
- User Authentication: Verify username and password against database
- Generate JWT: Create token with user ID, role, and expiration
- Return Token: Send JWT to client (avoid storing in localStorage for XSS protection)
- Token Usage: Client includes JWT in Authorization header for API requests
- Token Verification: Server validates signature and expiration on each request
- Use secure HTTP-only cookies for storage
- Implement token refresh mechanism
- Set appropriate expiration times
- Include rate limiting
- Storing tokens in localStorage
- Not implementing logout/revocation
- Using long expiration times
- Exposing sensitive data in claims
Scenario 2: API Access Control
Using JWTs to control access to API endpoints based on user roles and permissions.
{
"sub": "api_user_789",
"iss": "api.mycompany.com",
"aud": ["api.mycompany.com", "mobile.mycompany.com"],
"exp": 1641001200,
"iat": 1640997600,
"scope": ["read:users", "write:posts", "admin:dashboard"],
"rate_limit": 1000
}1Scope-based permissions: define what actions the token holder can perform2Audience validation: ensure token is intended for your API3Rate limiting: include usage limits to prevent abuseScenario 3: Microservices Communication
Secure communication between microservices using JWTs for service-to-service authentication.
{
"sub": "order-service",
"iss": "auth-service",
"aud": ["inventory-service", "payment-service"],
"exp": 1641001200,
"service_id": "order-svc-001",
"permissions": ["read:inventory", "write:payments"]
}Each service validates tokens before processing requests, ensuring only authorized services can interact.
Security Deep Dive
Algorithm Confusion Attacks
Attackers change the algorithm from RS256 to HS256, then use the public key as the HMAC secret. Prevention: always specify expected algorithms in your verification code.
// Good: Specify allowed algorithms
jwt.verify(token, secret, { algorithms: ['HS256'] });
// Bad: Accept any algorithm
jwt.verify(token, secret);"None" Algorithm Bypass
Some JWT libraries accept "none" algorithm, which skips signature verification entirely.
{
"alg": "none",
"typ": "JWT"
}Weak Secret Keys
Short or predictable secrets can be brute-forced, allowing attackers to forge tokens.
Weak Secrets
- "secret"
- "password123"
- Company name
- Dictionary words
Strong Secrets
- 256+ bit random keys
- Use crypto.randomBytes(32)
- Store in environment variables
- Rotate regularly
Security Best Practices
Token Management
- Short expiration: 15-60 minutes for access tokens
- Refresh tokens: Longer-lived but revocable
- Revocation list: Track and invalidate compromised tokens
- Secure storage: HTTP-only cookies preferred
Implementation Security
- Algorithm allowlisting: Specify exact algorithms
- Audience validation: Verify aud claim
- Issuer validation: Verify iss claim
- Time validation: Check iat, exp, nbf claims
Troubleshooting Common Issues
"Invalid Signature" Errors
- Using different secrets for signing and verification
- Algorithm mismatch (e.g., signed with HS256, verified with RS256)
- Token corruption during transmission
- Clock skew between servers
Debug steps: Log the exact token, algorithm, and secret being used. Compare with original signing parameters.
"Token Expired" Errors
- Implement automatic token refresh before expiration
- Synchronize server clocks (use NTP)
- Add clock skew tolerance (leeway) to verification
- Use appropriate expiration times for your use case
Implementation tip: Refresh tokens when they're 80% through their lifespan.
"Malformed Token" Errors
- Check token format: three parts separated by dots
- Verify Base64URL encoding (not regular Base64)
- Ensure header and payload are valid JSON
- Check for extra whitespace or newlines
Quick test: Use jwt.io to decode your token and check for formatting issues.
Next Steps
Practice Exercises
- Build a complete login system with JWT
- Implement token refresh mechanism
- Create role-based access control
- Set up JWT revocation system
Advanced Topics
- JWE (JSON Web Encryption) for sensitive data
- JWK (JSON Web Keys) for key rotation
- OAuth 2.0 integration with JWTs
- Performance optimization for high-traffic apps