Skip to content

JWT Decoder

Decode and inspect JWT tokens with security warnings for expired or unsigned tokens

Your Auth is Broken. The Token Knows Why.

You’re getting 401 errors on an API call that worked yesterday. The frontend’s sending a token, the backend’s rejecting it, and the error message just says “Unauthorized.” Not helpful.

Paste the JWT here. Nine times out of ten, you’ll spot the problem immediately: the exp claim expired two hours ago, the aud (audience) doesn’t match your API’s expected value, or the iss (issuer) is pointing at your staging auth server instead of production.

JWTs are three Base64URL-encoded JSON objects separated by dots: header, payload, and signature. This tool decodes the first two and flags common security issues — expired tokens, the dangerous "alg": "none" header, missing critical claims. It runs entirely in your browser, which matters because tokens often contain user IDs, email addresses, roles, and permissions.

What to Look for in the Header

The header tells you the signing algorithm. Common ones:

  • HS256 — HMAC with a shared secret. Both the issuer and verifier need the same key. Fast and simple, but the secret has to stay secret on both ends.
  • RS256 — RSA with a public/private key pair. The issuer signs with the private key, anyone can verify with the public key. Better for distributed systems and microservices.
  • ES256 — ECDSA with elliptic curve keys. Smaller signatures than RSA, comparable security.

If you see "alg": "none", that’s a massive red flag. The token has no signature at all. Any attacker can craft a forged token with arbitrary claims. The “none” algorithm vulnerability has been exploited in real-world attacks against libraries that naively trust the header’s algorithm field.

Reading the Payload

The payload is where the actual data lives:

  • sub — the subject, usually a user ID
  • exp — expiration timestamp (Unix epoch). If the current time is past this, the token’s dead.
  • iat — “issued at” timestamp. Tells you when the token was created.
  • iss — issuer. Should match your auth server’s domain.
  • aud — audience. Should match the API or service the token is intended for.

Custom claims live here too — roles, permissions, tenant IDs, whatever your app puts in. Just remember: the payload isn’t encrypted. Anyone who intercepts the JWT can decode it and read everything. Don’t put sensitive data like passwords or credit card numbers in JWT payloads.

Debugging Real Problems

Token expired 5 minutes ago. Your frontend grabbed the token from localStorage, but it’s stale. Your app needs a refresh token flow.

Wrong audience claim. You deployed a new service at a different URL, but the auth server is still issuing tokens with the old audience. Update your auth config.

Clock skew. Your server is 90 seconds ahead of the auth server. Tokens look expired even though they were just issued. Sync your server clocks with NTP and add a small leeway (30-60 seconds) to your verification.

This tool doesn’t verify signatures — that would require your secret key or public key, and you shouldn’t paste those into a browser tool. For verifying HS256 signatures manually, compute the HMAC of the header.payload string using the HMAC Generator on Toolsvu. For the underlying Base64 encoding, the Base64 Encode / Decode tool is available.

jwt decoder token security authentication

Related Tools

More in Security Tools