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_adQssw5c

Header

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.

Header JSON:
{
  "alg": "HS256",
  "typ": "JWT"
}
Base64URL Encoded:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
💡 Try It: Use our JWT generator to experiment with different algorithms like RS256 or ES256.

Step 2: Create the Payload

The payload contains claims about the user and session. Include essential information but keep it lean.

Payload JSON:
{
  "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
⚠️ Security Note:
  • • 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 Algorithm:
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.k8GTeGOJhBtC1esXPRYGHQMnM2s6i4DYvAkGNDqHlJM
🎉 Congratulations! You've created your first JWT. This token can now be used for authentication.

Interactive 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-6SxlsEoaVQFhpvEp7WLLhRqXXXjQfbTc
1. Decode Header
Encoded:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Decoded:
{
  "alg": "HS256",
  "typ": "JWT"
}
2. Decode Payload
Encoded:
eyJzdWIiOiJ1c2VyNDU2Ii...
Decoded:
{
  "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)
⚠️ Common Validation Mistakes
  • • 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:

  1. 1. User Authentication: Verify username and password against database
  2. 2. Generate JWT: Create token with user ID, role, and expiration
  3. 3. Return Token: Send JWT to client (avoid storing in localStorage for XSS protection)
  4. 4. Token Usage: Client includes JWT in Authorization header for API requests
  5. 5. Token Verification: Server validates signature and expiration on each request
✅ Best Practices
  • • Use secure HTTP-only cookies for storage
  • • Implement token refresh mechanism
  • • Set appropriate expiration times
  • • Include rate limiting
❌ Common Pitfalls
  • • 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.

Sample API JWT Payload:

{
  "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
}
1
Scope-based permissions: Define what actions the token holder can perform
2
Audience validation: Ensure token is intended for your API
3
Rate limiting: Include usage limits to prevent abuse

Scenario 3: Microservices Communication

Secure communication between microservices using JWTs for service-to-service authentication.

Service JWT Example:

{
  "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

🚨 Critical Security Issues

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.

Example malicious header:
{
  "alg": "none",
  "typ": "JWT"
}
Prevention: Explicitly reject "none" algorithm in your code

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

Common causes:

  • 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

Solutions:

  • 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

Validation steps:

  • 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

🚀 Continue Your JWT Journey

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
💡 Pro Tip: Generate secure JWT secrets and experiment with different algorithms using our JWT secret generator. Practice makes perfect when it comes to JWT security!