JWT Token Debugging: The Complete Guide
Learn how to decode, inspect, and debug JWT tokens with practical techniques and common pitfall solutions.
JSON Web Tokens (JWT) are the backbone of modern authentication systems. When things go wrong, knowing how to debug them quickly is essential.
JWT Structure Breakdown
A JWT consists of three Base64URL-encoded parts separated by dots:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N...
|--- Header ---|.|----- Payload ------|.|----- Signature ------|
Decoding Without Verification
function decodeJWT(token) {
const parts = token.split('.');
if (parts.length !== 3) throw new Error('Invalid JWT format');
const header = JSON.parse(atob(parts[0]));
const payload = JSON.parse(atob(parts[1]));
return { header, payload, signature: parts[2] };
}
Common JWT Debugging Issues
1. Token Expiration (exp claim)
The most frequent issue. The exp claim is a Unix timestamp in seconds:
const payload = decodeJWT(token).payload;
const now = Math.floor(Date.now() / 1000);
const expiresIn = payload.exp - now;
if (expiresIn < 0) {
console.log('Token expired ' + Math.abs(expiresIn) + ' seconds ago');
}
2. Clock Skew
Servers with slightly different clocks can cause premature token rejection. Most JWT libraries allow a configurable leeway of 30-60 seconds.
3. Algorithm Confusion Attacks
Always explicitly verify the algorithm used:
// SAFE: explicitly specify the algorithm
jwt.verify(token, secret, { algorithms: ['HS256'] });
Debugging Checklist
1. Is the token well-formed? — Does it have exactly 3 dot-separated parts?
2. Is it expired? — Check the exp claim against current time
3. Is the audience correct? — Verify the aud claim matches your service
4. Is the issuer correct? — Verify the iss claim
5. Is the signature valid? — Use the correct secret/public key
6. Is the algorithm correct? — Don't accept none or unexpected algorithms
Use our JWT Decoder tool to quickly inspect and debug JWT tokens without writing any code.