Developer Tools

JWT Decoder Guide: Understanding JSON Web Tokens

· QuickToolFlow
jwt authentication security web development api

JSON Web Tokens are the backbone of modern web authentication. If you work with APIs, single sign-on, or any authentication system, you have encountered JWTs.

This guide explains what JWTs are, how they are structured, how to decode them, and what to look out for.

To inspect a real token while following along, use the JWT Decoder. For the underlying encoding layer, the Base64 Encoder and Decoder can help you understand how token sections are represented as text.


What Is a JWT?

A JWT (pronounced “jot”) is a compact, URL-safe token format for securely transmitting information between two parties. It is defined in RFC 7519.

A JWT looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

It has three parts separated by dots: Header . Payload . Signature.


The Three Parts of a JWT

The header contains metadata about the token:

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg — The signing algorithm (HS256, RS256, ES256, etc.)
  • typ — The token type (always "JWT")

Payload

The payload contains the claims — the actual data being transmitted:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Common registered claims:

ClaimNamePurpose
subSubjectThe user ID or unique identifier
issIssuerWho issued the token
audAudienceWho the token is intended for
expExpirationWhen the token expires (Unix timestamp)
nbfNot BeforeWhen the token becomes valid (Unix timestamp)
iatIssued AtWhen the token was issued (Unix timestamp)
jtiJWT IDA unique identifier for the token

You can also include custom claims like name, email, roles, and permissions.

Signature

The signature is created by combining the encoded header and payload with a secret key using the algorithm specified in the header:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

The signature ensures the token has not been tampered with.


How JWT Authentication Works

  1. User logs in — The server verifies credentials (username and password).
  2. Server creates a JWT — The server encodes the user data into a JWT with an expiration time.
  3. Client stores the JWT — The browser stores it in a cookie or localStorage.
  4. Client sends the JWT — On each request, the client includes the JWT in the Authorization header: Authorization: Bearer <token>.
  5. Server verifies the JWT — The server checks the signature and expiration. If valid, the request proceeds.

Decoding vs Verifying a JWT

Decoding and verifying are often confused. Decoding only reads the header and payload. Verification checks whether the signature is valid and whether the token should be trusted.

You can decode most JWTs without a secret because the header and payload are Base64Url encoded, not encrypted. That is useful for debugging claims such as sub, aud, iss, and exp.

Verification requires the correct secret or public key. Without verification, the payload is only text supplied by whoever created the token. A malicious user can create a token that looks convincing if your server does not verify the signature.

Use a decoder to inspect and understand. Use your authentication library on the server to verify and authorize.

What to Check When Debugging Auth

When a request fails with an authentication error, inspect the decoded token carefully:

  • Does exp show the token is expired?
  • Does nbf say the token is not valid yet?
  • Does aud match the API receiving the request?
  • Does iss match the expected identity provider?
  • Does the token contain the role or permission your route expects?
  • Is the algorithm in the header what your server is configured to accept?

Time-based claims are Unix timestamps. If they are hard to read, convert them with the Timestamp Converter before assuming the auth system is broken.

Safe Handling Rules

Do not paste production access tokens into public chats, issue trackers, screenshots, or shared documents. Even if a JWT is expired, it may reveal user IDs, tenant IDs, email addresses, scopes, or internal system names.

If you need to share a token example, create a synthetic token with fake claims. For debugging, copy only the decoded claim names and relevant timestamps when possible.


How to Decode a JWT

JWTs use Base64Url encoding (not standard Base64). To decode manually:

  1. Split the token at the dots.
  2. Take each part and convert from Base64Url to regular Base64 (replace - with + and _ with /).
  3. Add padding (=) if needed.
  4. Decode from Base64 to get the JSON string.
  5. Parse the JSON.

JavaScript

function decodeJwt(token) {
  var parts = token.split('.');
  var payload = parts[1];
  var decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
  return JSON.parse(decoded);
}

Python

import base64
import json

def decode_jwt(token):
    payload = token.split('.')[1]
    padding = 4 - len(payload) % 4
    payload += '=' * padding
    decoded = base64.urlsafe_b64decode(payload)
    return json.loads(decoded)

PHP

$token = 'eyJhbGciOiJIUzI1NiIs...';
$parts = explode('.', $token);
$payload = $parts[1];
$payload = str_replace(['-', '_'], ['+', '/'], $payload);
$payload .= str_repeat('=', 4 - strlen($payload) % 4);
$decoded = base64_decode($payload);
$data = json_decode($decoded, true);
print_r($data);

Security Considerations

Never trust the payload without verification Decoding a JWT does not mean it is valid. Anyone can decode and read a JWT because the payload is only Base64 encoded, not encrypted. Never store sensitive information like passwords in the payload.

Always verify the signature The signature is the only part that ensures the token is authentic. Use your server’s secret key to verify the signature before trusting any claims.

Use strong algorithms

  • HS256 (HMAC with SHA-256) — Good for most applications with a strong secret key.
  • RS256 (RSA with SHA-256) — Better for distributed systems where you need separate signing and verification keys.
  • none algorithm — Some older libraries accept tokens with no signature. Always reject these.

Set short expiration times Access tokens should expire quickly (15 minutes to 1 hour). Use refresh tokens for longer sessions.

Avoid localStorage for sensitive apps localStorage is vulnerable to XSS attacks. For sensitive applications, store tokens in HttpOnly cookies that JavaScript cannot access.


Conclusion

JWTs are a powerful and widely used authentication mechanism. Understanding their structure — header, payload, and signature — helps you implement secure authentication, debug token issues, and avoid common security mistakes. Always verify signatures on the server side, set short expiration times, and never trust the decoded payload without verification.

Keep going

Related tools and guides

All tools