How to Decode a JWT Token: Header, Payload & Signature Explained
JWT (JSON Web Token) is the standard for authentication tokens in modern APIs. Understanding how to decode one — and what each part means — is an essential skill for any developer working with web services.
What is a JWT?
A JSON Web Token is a compact, URL-safe way to represent claims between two parties. In practice, you get a JWT from a login API, then send it in every subsequent request as proof of your identity. The server validates the token without needing to look up a session in a database.
A JWT looks like three Base64url-encoded strings separated by dots:
The three parts are: Header · Payload · Signature
Part 1: The Header
The header is a Base64url-encoded JSON object describing the token type and the signing algorithm used. Decode the first segment and you get:
{
"alg": "HS256", // signing algorithm: HMAC-SHA256
"typ": "JWT" // token type
}Common algorithm values include HS256 (HMAC with SHA-256), RS256 (RSA with SHA-256), and ES256 (ECDSA). The algorithm tells the recipient how to verify the signature.
Part 2: The Payload
The payload contains the "claims" — statements about the user and any additional metadata. Decode the second segment:
{
"sub": "1234567890", // subject (user ID)
"name": "John Doe", // custom claim
"iat": 1516239022, // issued at (Unix timestamp)
"exp": 1516242622, // expiration (Unix timestamp)
"role": "admin" // custom claim
}Standard registered claims include:
sub— Subject: identifies the user (usually a user ID)iat— Issued At: when the token was created (Unix timestamp)exp— Expiration: when the token expires — after this time, reject itnbf— Not Before: the token is not valid before this timeiss— Issuer: who issued the token (e.g., "auth.myapp.com")aud— Audience: intended recipient of the token
Part 3: The Signature
The signature verifies the token hasn't been tampered with. It's created by taking the encoded header, a dot, the encoded payload, signing that with a secret key using the specified algorithm, then Base64url-encoding the result.
signature = HMACSHA256( base64url(header) + "." + base64url(payload), secret_key )
How to check if a JWT is expired
The exp claim is a Unix timestamp (seconds since Jan 1, 1970). To check expiry in JavaScript:
function isExpired(token) {
const payload = JSON.parse(atob(token.split('.')[1]));
if (!payload.exp) return false; // no expiry set
return Date.now() / 1000 > payload.exp;
}
// Usage
if (isExpired(myToken)) {
// redirect to login
}Manually decoding a JWT in the browser console
const token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U";
const [header, payload, sig] = token.split('.');
// Decode header
JSON.parse(atob(header));
// { alg: "HS256", typ: "JWT" }
// Decode payload
JSON.parse(atob(payload));
// { sub: "1234567890" }Note: atob() works for standard Base64. For Base64url (which JWT uses), you may need to replace - with + and _ with / before decoding.
Paste any JWT token to instantly see the decoded header, payload, and expiration status.
Open JWT Decoder →