JWT Security

Decode JWT Tokens Without
Sending Them to a Server

That token contains your user's identity, permissions and session data. Here's why you should never paste it into a random website.

5 min read·Updated Feb 2026

JWT tokens look like random garbage — three base64 strings separated by dots. When you need to inspect one, the instinct is to Google "JWT decoder" and paste it in. That's exactly what dozens of online tools are counting on.

What's Actually Inside a JWT

A JWT has three parts: header, payload and signature. The payload is the interesting part — it typically contains:

If the token is still valid when you paste it into an online tool, you've just handed a live authentication credential to a third-party server.

The Scenario That Goes Wrong

You're debugging an auth failure in production. You copy a real user's JWT from a log, paste it into an online decoder to check the claims. The token has 6 hours left on it. If that online tool logs requests — or has been compromised — that token can now be used to impersonate your user.

Wait — Is jwt.io Safe?

jwt.io is the most popular JWT debugger and it's operated by Auth0 (now Okta). According to their documentation, decoding is done client-side in JavaScript. That's better than most alternatives.

However: it's still a third-party website. You're trusting that their JavaScript hasn't been tampered with, that their CDN hasn't been compromised, and that no browser extension is intercepting the paste. For production tokens with sensitive claims, "probably fine" isn't good enough.

The Safe Alternative: Decode Locally

JWT decoding is simple math — the payload is just base64 encoded. You don't need a server to do it. You can do it in:

Option 1: ResourceCentral's Free JWT Decoder (Recommended)

ResourceCentral's JWT Decoder runs entirely in your browser. Paste your token, see the header and payload instantly. Nothing is transmitted. You can verify this by opening DevTools → Network tab — zero requests during decoding.

Option 2: Your Browser Console

If you want zero dependencies, open the browser console and run:

const token = 'eyJhbGci...your.token.here';
const [header, payload] = token.split('.');
console.log(JSON.parse(atob(header)));
console.log(JSON.parse(atob(payload)));

This decodes the token using only built-in browser APIs. Nothing leaves your machine.

Option 3: Command Line

# Decode the payload (middle section)
echo "eyJzdWIiOiIxMjM0NTY3ODkwIn0" | base64 --decode | python3 -m json.tool

What to Check When Debugging JWT Issues

Most JWT debugging involves checking one of these things:

exp claim

Is the token expired? exp is a Unix timestamp. Compare to Date.now()/1000.

aud claim

Is the audience correct? Wrong aud causes "invalid audience" errors.

iss claim

Is the issuer matching your expected auth server URL?

Custom claims

Are the roles, permissions or org IDs present and correct?

All of these are visible in the decoded payload — no server needed, no secret key needed.

A Note on Signature Verification

Decoding a JWT (reading the claims) is different from verifying it (checking the signature). Verification requires your secret key and should only happen server-side. Never put your JWT signing secret into any online tool. Ever.

For debugging purposes, you almost never need to verify the signature — you just need to read the claims. Decoding is safe and can be done entirely client-side.

Decode JWT Tokens Privately — Free

Client-side only. Zero network requests. Works offline.

Open JWT Decoder — Free →

FAQ

Do I need the secret key to decode a JWT? +

No. The header and payload are base64 encoded, not encrypted. Anyone can decode them without the secret key. The secret is only needed to verify the signature — a separate operation.

Can an expired JWT still be dangerous to share? +

Expired tokens can't be used for authentication, but they still contain PII (user ID, email, roles). Treat expired tokens as sensitive — they're a data privacy concern even if not a security one.

Related