JWT Decoder: Decode, Debug & Verify JSON Web Tokens

TK
Toolshubkit Editor
Published Jan 2025
9 MIN READ • Privacy & Security
JSON Web Tokens (JWT) are the backbone of stateless authentication in modern web apps. Our JWT Debugger lets you decode any token, inspect claims, and verify expiry — entirely in your browser, with zero server contact.

Technical Mastery Overview

Real-time Decoding
Hover-to-Date Timestamps
Visual Session Expiry
Local Privacy Sandbox

What Is a JSON Web Token?

A JSON Web Token is a compact, URL-safe string used to transmit claims between two parties. You'll encounter JWTs as the value of Authorization: Bearer <token> headers, inside cookies, or embedded in OAuth callback URLs. They're produced by identity providers (Auth0, Cognito, Firebase Auth, Keycloak) and consumed by your API to verify who the caller is and what they're allowed to do.

A raw JWT looks like this:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsIm5hbWUiOiJKYW5lIERvZSIsImlhdCI6MTcwOTI5NjAwMCwiZXhwIjoxNzA5MzgyNDAwLCJyb2xlIjoiYWRtaW4ifQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Three Base64URL-encoded segments separated by dots. The dots are load-bearing — strip one and the token is instantly invalid.

The Three-Part Structure

Header — the first segment — decodes to:

{
  "alg": "RS256",
  "typ": "JWT"
}

alg tells the receiver which signing algorithm was used. RS256 means the token was signed with a private RSA key and can be verified with the corresponding public key. HS256 means a shared secret was used for HMAC-SHA256. The algorithm matters enormously for security — more on that below.

Payload — the second segment — decodes to the claims:

{
  "sub": "user_123",
  "name": "Jane Doe",
  "iat": 1709296000,
  "exp": 1709382400,
  "role": "admin",
  "iss": "https://auth.example.com",
  "aud": "https://api.example.com"
}

Signature — the third segment — is the cryptographic proof. You cannot decode a valid signature without the key; you can only verify it. Our JWT Debugger decodes the header and payload (which are just Base64URL, not encrypted) and makes claims readable — but it correctly does not claim to verify signatures without a key.

Registered Claims You Must Know

The JWT spec (RFC 7519) reserves a set of claim names. These aren't enforced by the format itself — they're conventions your application must check:

Claim Full name What it means
sub Subject Unique identifier for the user (user ID, UUID)
iss Issuer Who created the token (your auth server URL)
aud Audience Who the token is intended for (your API URL)
exp Expiration Unix timestamp after which the token is invalid
iat Issued at Unix timestamp of when the token was created
nbf Not before Token is invalid before this timestamp
jti JWT ID Unique token ID, used for revocation lists

When you paste a token into our debugger, all Unix timestamps are converted to your local timezone automatically — you can see at a glance whether a session has expired, without running date -d @1709382400 in a terminal.

JWT vs. Session Tokens: When to Use Each

A common architectural question. Here's how they compare:

JWT (stateless) Server sessions (stateful)
Storage Client-side (cookie or localStorage) Server-side (Redis, DB)
Revocation Hard — token valid until exp Instant — delete the session
Scalability Excellent — any server validates Requires shared session store
Payload size Grows with claims Fixed (session ID only)
Offline use Yes No
Best for Microservices, APIs, mobile Traditional web apps, admin tools

The key tradeoff: JWTs cannot be revoked mid-flight unless you maintain a token blocklist — which reintroduces statefulness. If you need instant logout (financial apps, security-sensitive admin panels), either use short expiry + refresh tokens or stick with server sessions.

Common Debugging Scenarios

1. "401 Unauthorized" errors

The most common cause is an expired exp claim. Paste the token into the debugger, check the expiry timestamp. If it's in the past, your client-side token refresh logic has a bug or the user needs to re-authenticate.

2. "Invalid audience" errors

Your API is validating the aud claim and the token was issued for a different audience. Check that your auth server is including the correct API URL in the audience, and that your middleware is checking against the right value.

3. Missing role or permission claims

Authorization middleware that checks role: "admin" or scopes will silently fail if the claim isn't present. Decode the token to confirm the claim exists and is spelled correctly — roles vs role vs scope vs permissions are all different keys.

4. Clock skew issues

iat or nbf in the future? Your auth server's clock may be ahead of your API server's clock. JWT libraries typically allow a few seconds of skew. If you're seeing consistent nbf validation failures, check NTP sync on your servers.

Use our Timestamp Converter to translate any Unix timestamp in a claim to a human-readable datetime for cross-referencing with your logs.

The alg: none Vulnerability

One of the most critical JWT security vulnerabilities: some libraries historically accepted "alg": "none" in the header, bypassing signature verification entirely. An attacker could craft a token with arbitrary claims, set the algorithm to none, strip the signature, and gain unauthorized access.

The fix: always specify an explicit allowlist of accepted algorithms in your JWT library configuration. Never accept none. Use RS256 or ES256 (asymmetric) for multi-service architectures, and HS256 (symmetric) only when all consumers share the secret securely.

// Correct — explicit algorithm allowlist
jwt.verify(token, publicKey, { algorithms: ['RS256'] });

// Dangerous — algorithm from token header is trusted implicitly
jwt.verify(token, publicKey); // some older libraries had this bug

Signing Algorithm Selection Guide

Algorithm Type Key material Use when
HS256 Symmetric (HMAC) Shared secret Single service, secret stays internal
HS512 Symmetric (HMAC) Shared secret Same as HS256 but stronger hash
RS256 Asymmetric (RSA) Private + public key Multiple services, public key distributed
ES256 Asymmetric (ECDSA) Private + public key Same as RS256 but smaller tokens
RS512 Asymmetric (RSA) Private + public key Higher security requirement

For generating the secrets used in HS256 signing, use our Password Generator with 32+ characters and full character set — the entropy of your secret is your security ceiling.

Refresh Tokens and Short-Lived Access Tokens

Best practice is to issue short-lived access tokens (15 minutes) paired with long-lived refresh tokens (7–30 days). The access token goes in the Authorization header; the refresh token is stored in an HttpOnly cookie. When the access token expires, the client silently exchanges the refresh token for a new pair.

This pattern limits the blast radius of a stolen token while keeping the user experience smooth. Decode your access token's exp to confirm your token lifetimes are configured correctly — many teams discover their tokens are set to 24 hours or 7 days with no refresh mechanism, which is both a security and UX problem.

Security: Why Local Decoding Matters

Many online JWT decoders send your token to their servers. This is a critical mistake — JWTs often contain sensitive user identifiers, role assignments, and in poorly designed systems, actual PII. A compromised decoder server can harvest tokens that are still valid.

Our debugger processes everything on your CPU. The decoding logic is JavaScript running in your browser tab. Nothing is transmitted. This local-first architecture means you can safely paste production tokens from your staging environment or debugging sessions.

If you need to share a token structure with a colleague, strip the signature first and redact the sub and any PII claims — or use our PII Redactor to sanitize the payload before sharing.

Inspecting JWKS Endpoints

In RS256 setups, the public key used for signature verification is published at a JWKS (JSON Web Key Set) endpoint — usually /.well-known/jwks.json on your auth server. The kid (key ID) claim in the JWT header tells the verifier which key to use from the set.

If you're debugging an invalid signature error with RS256, check:

  1. Does the kid in the token header match a key ID in the JWKS endpoint?
  2. Is the iss claim pointing to the correct auth server?
  3. Has the signing key been rotated without updating your cached public key?

Verification vs. Decoding

Decoding a JWT is not the same as verifying it. Anyone can decode a JWT — it's just Base64URL encoding, not encryption. The payload claims are not secret; they're simply not tamper-proof without the signature check. Verification requires the public or private key used by the issuer and is what your backend middleware performs on every request.

Use the debugger to inspect content and understand structure. Use your backend JWT library (jsonwebtoken, python-jose, golang-jwt) to perform cryptographic verification in production.

Workflow Integration

Pair the JWT Debugger with:

Experience it now.

Use the professional-grade JWT Debugger with zero latency and 100% privacy in your browser.

Launch JWT Debugger
Debugging authentication starts with understanding what's inside your tokens. Decode them locally, audit claims systematically, and combine with hash and PII tools to keep your auth stack airtight.