ByteTools Logo

JWT Decoding Guide: How to Decode and Verify JSON Web Tokens

Master JWT decoding and verification for secure authentication. Learn token structure, claims validation, signature verification, and security best practices.

What is JWT?

JWT (JSON Web Token) is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. JWTs are commonly used for authentication and information exchange in web applications.

Why Use JWT?

Benefits

  • Stateless - No server-side session storage
  • Portable - Can be used across different domains
  • Compact - Small size for HTTP headers
  • Self-contained - Contains all necessary information

Considerations

  • Size - Larger than session IDs
  • Cannot revoke - Valid until expiration
  • Sensitive data - Payload is readable
  • Key management - Requires secure secret handling

JWT Structure

A JWT consists of three Base64-encoded parts separated by dots:

header.payload.signature
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Header

Contains metadata about the token:

{
"alg": "HS256",
"typ": "JWT"
}
  • alg: Signing algorithm
  • typ: Token type

Payload

Contains claims (statements about the user):

{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1516242622
}
  • sub: Subject (user ID)
  • iat: Issued at time
  • exp: Expiration time

Signature

Verifies token integrity:

HMACSHA256(
base64UrlEncode(header) +
"." +
base64UrlEncode(payload),
secret
)
  • • Prevents tampering
  • • Requires secret key
  • • Verifies authenticity

JWT Decoding Process

Decoding a JWT involves extracting and parsing each part:

Step-by-Step Decoding

1

Split the Token

Separate the token at the dots (.) to get three parts

const [header, payload, signature] = token.split('.');
2

Base64 Decode

Decode each part from Base64URL encoding

const decodedHeader = JSON.parse(atob(header));
const decodedPayload = JSON.parse(atob(payload));
3

Parse JSON

Convert the decoded strings to JSON objects

// Now you have readable header and payload objects

Important Note

Decoding only reveals content - it doesn't verify authenticity. Always validate the signature on the server!

Understanding JWT Claims

Claims are statements about an entity (typically the user) and additional data:

Standard Claims

"iss" (Issuer)
Who issued the token
Example: "https://auth.example.com"
"sub" (Subject)
Who the token is about
Example: "user123" or "john@example.com"
"aud" (Audience)
Who should accept the token
Example: "api.example.com"
"exp" (Expiration)
When the token expires
Unix timestamp: 1704067200
"iat" (Issued At)
When the token was issued
Unix timestamp: 1704063600

Custom Claims

"name"
User's full name
Example: "John Doe"
"email"
User's email address
Example: "john@example.com"
"roles"
User's permissions/roles
Example: ["admin", "user"]
"permissions"
Specific permissions
Example: ["read:posts", "write:posts"]
"tenant_id"
Multi-tenant identifier
Example: "company-abc"

Security Reminder

Never include sensitive information like passwords, social security numbers, or private keys in JWT payload. The payload is only Base64-encoded, not encrypted!

Common Debugging Scenarios

"Token Expired" Errors

When users get authentication failures, check the token expiration:

// Check exp claim
const now = Math.floor(Date.now() / 1000);
const isExpired = payload.exp < now;

Debug Steps:

  • 1. Decode the JWT to see the exp claim
  • 2. Convert Unix timestamp to readable date
  • 3. Compare with current time
  • 4. Check token refresh logic

Permission Debugging

When users can't access resources, check roles and permissions:

// Check roles in payload
const userRoles = payload.roles || [];
const hasAdminRole = userRoles.includes('admin');

Debug Steps:

  • 1. Decode JWT and examine roles claim
  • 2. Check permissions array if present
  • 3. Verify role-to-permission mapping
  • 4. Test with different user accounts

Invalid Signature

When signature verification fails:

// Common causes:
- Wrong secret key
- Token was modified
- Different algorithm used

Debug Steps:

  • 1. Verify the signing algorithm in header
  • 2. Check if secret key matches
  • 3. Ensure token wasn't tampered with
  • 4. Validate key rotation timing

Malformed Token

When token structure is invalid:

// Valid JWT structure:
header.payload.signature
// Must have exactly 3 parts

Debug Steps:

  • 1. Count dots (.) - should be exactly 2
  • 2. Check for truncated tokens
  • 3. Verify Base64 encoding
  • 4. Test with a known good token

Security Best Practices

Security Do's

  • Use HTTPS - Always transmit JWTs over encrypted connections
  • Short expiration times - Use 15-60 minutes for access tokens
  • Strong secrets - Use cryptographically secure random keys
  • Validate all claims - Check iss, aud, exp on every request
  • Use refresh tokens - Implement proper token refresh flow
  • Store securely - Use secure, httpOnly cookies when possible

Security Don'ts

  • Don't store sensitive data - Payload is readable by anyone
  • Don't use weak secrets - Avoid predictable or short keys
  • Don't skip signature verification - Always validate server-side
  • Don't use "none" algorithm - Disabled unsigned tokens
  • Don't store in localStorage - Vulnerable to XSS attacks
  • Don't ignore expiration - Always check exp claim

Algorithm Security

Recommended

  • HS256 - HMAC with SHA-256
  • RS256 - RSA with SHA-256
  • ES256 - ECDSA with SHA-256

Deprecated

  • HS1 - Weak hash function
  • RS1 - Vulnerable to attacks
  • • Custom algorithms

Never Use

  • none - No signature
  • HS0 - No security
  • • MD5-based algorithms

Common Issues & Solutions

Clock Skew Issues

Problem:

Server and client clocks are out of sync, causing premature token expiration.

Solution:

  • • Add clock skew tolerance (usually 5 minutes)
  • • Use NTP to sync server clocks
  • • Implement proper time validation

Token Refresh Problems

Problem:

Users get logged out frequently due to short token lifetimes.

Solution:

  • • Implement refresh token flow
  • • Auto-refresh before expiration
  • • Use sliding expiration windows

Mobile App Considerations

Challenges:

  • • App backgrounding affects timers
  • • Network connectivity issues
  • • Secure storage limitations

Best Practices:

  • • Use device keychain/keystore
  • • Implement offline token validation
  • • Handle app lifecycle events

Testing Your JWT Implementation

Test Cases:

  • • Valid token acceptance
  • • Expired token rejection
  • • Invalid signature detection
  • • Malformed token handling

Security Tests:

  • • Algorithm confusion attacks
  • • None algorithm bypass
  • • Key confusion attacks
  • • Token replay attacks

Tools:

Ready to Decode Your JWT Tokens?

Use our secure JWT decoder with claim validation, signature verification, and detailed token analysis.

Start Decoding JWT Tokens Now