1. The Anatomy of a JSON Web Token (JWT)
A JSON Web Token is a compact, URL-safe means of representing claims to be transferred between two parties. Structurally, a JWT consists of three Base64URL-encoded parts separated by periods (.):
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
- Header: Typically consists of the token type (
JWT) and the signing algorithm being used, such asHMAC SHA256(HS256) orRSA SHA256(RS256). - Payload (Claims): Contains the claims. Claims are statements about an entity (typically, the user) and additional metadata like
iss(issuer),exp(expiration time),iat(issued at), andsub(subject). - Signature: Generated by taking the encoded header, the encoded payload, a secret key, and passing them into the specified hashing algorithm.
2. Understanding Standard Registered Claims
To ensure interoperability, the JWT specification defines standard reserved claim keys:
iss(Issuer): Identifies the principal that issued the JWT.sub(Subject): Identifies the principal that is the subject of the JWT (e.g., user UUID).aud(Audience): Identifies the recipients that the JWT is intended for.exp(Expiration Time): Unix timestamp after which the JWT must not be accepted for processing.nbf(Not Before): Unix timestamp before which the JWT must not be accepted.iat(Issued At): Unix timestamp when the token was created.
3. Top 5 Security Pitfalls in JWT Implementation
- Accepting the 'none' Algorithm: Never trust the
algheader blindly from the client. Enforce a strict algorithm whitelist on your server. - Weak Symmetric Keys (HS256): Using short, guessable secret keys allows attackers to brute-force the secret offline and forge valid admin tokens. Use cryptographic keys with at least 256 bits of entropy.
- Storing Sensitive PII in Payloads: JWT payloads are Base64URL encoded, NOT encrypted. Anyone who intercepts the token can read passwords, email addresses, or internal IPs unless you use JWE (JSON Web Encryption).
- Infinite Token Lifetimes: Always set reasonable expiration times (e.g., 15 minutes for access tokens) combined with refresh tokens.
- Lack of Revocation Strategy: Because JWTs are stateless, revoking a compromised token before expiration requires token versioning or a Redis blocklist.
4. How to Decode JWTs Securely in JavaScript
Here is how you can parse a JWT payload on the client side without external libraries:
function parseJwt(token) {
try {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(
atob(base64)
.split('')
.map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
.join('')
);
return JSON.parse(jsonPayload);
} catch (err) {
console.error('Invalid JWT token:', err);
return null;
}
}