🔐 Decode • Validate • Verify

JWT Debugger & Inspector

Paste a JSON Web Token to instantly decode its header and payload, inspect every claim, run an automated security analysis, and verify HS/RS/PS/ES signatures — entirely in your browser. Nothing is ever uploaded.

🔒 Browser-based 🚫 No upload, ever 🔑 Real Web Crypto verification 🛡️ Automated security analysis 🆓 Free forever 📱 Mobile friendly
🛠️ Generate a JWT

🔗 Encoded token

0 characters · 0 / 3 segments

The color-coded token will appear here…
HEADER · algorithm & type
PAYLOAD · claims / data

✅ Verify signature alg: —

Status: Enter a secret or public key to verify

For RSA/ECDSA tokens (RS/PS/ES), paste a PEM public key instead of a secret.

Decoding needs no key at all — anyone can read a JWT's header and payload. Verification is the separate, cryptographic step that confirms the token wasn't tampered with.

💡 Tip: drag & drop a .txt/.json file containing a token anywhere on the input box, or paste with Ctrl/Cmd+V. Everything above updates live as you type — nothing is ever uploaded.

Why this is the best JWT debugger online

Built for real authentication debugging, not just a pretty-print demo.

🔒

100% private

Your token, secrets and keys are decoded and verified entirely in your browser — never uploaded, logged, or stored.

🔑

Real cryptographic verification

Uses the browser's native Web Crypto API for genuine HS/RS/PS/ES signature checks — not a visual simulation.

🛡️

Automated security analysis

Flags the "none" algorithm, missing expiration, very long lifetimes, weak secrets and possible sensitive data in the payload.

📊

Token insights dashboard

Algorithm, size, segment count, claim count, expiration status and a heuristic security score at a glance.

📋

Full claims breakdown

Every registered claim (iss, sub, aud, exp, nbf, iat, jti) gets a human-readable date and countdown, plus any custom claims.

📱

Mobile-first & accessible

Large touch targets, a sticky decode bar, dark mode and full keyboard/screen-reader support out of the box.

How to decode and verify a JWT in 4 steps

No install, no account — go from a raw token to a full inspection in seconds.

Paste your token

Paste, type, drag & drop a file, or load the sample JWT.

Review the decode

Header, payload, claims, insights and security analysis all update instantly.

Verify the signature

Enter the secret (HS) or paste a PEM public key (RS/PS/ES) to confirm authenticity.

Copy or export

Copy or download the decoded header and payload as JSON for use elsewhere.

JWT compared to other approaches

Context for choosing the right authentication or token strategy.

JWT vs. session-based authentication

AspectJWT (stateless)Server sessions (stateful)
Where state livesEntirely inside the token itselfIn server-side storage (memory, Redis, DB)
RevocationHard — valid until it expires, unless you add a blocklistEasy — delete the session server-side
Scales across serversNaturally — any server can verify itNeeds shared/centralized session storage
Payload visibilityReadable by anyone who has the tokenOpaque session ID only

HS256 vs. RS256

AspectHS256 (symmetric)RS256 (asymmetric)
KeysOne shared secret signs and verifiesPrivate key signs, public key verifies
Best forA single trusted backend issuing and checking its own tokensMultiple services verifying tokens from one central issuer
Key exposure riskAnyone with the secret can forge tokensPublic key can be shared freely without forgery risk

JWT vs. OAuth 2.0

AspectJWTOAuth 2.0
What it isA token formatAn authorization framework/protocol
RelationshipOften used as the access/ID token format inside OAuth flowsDefines how tokens (JWT or opaque) are issued and exchanged
Can exist without the other?Yes — JWTs are used outside OAuth tooYes — OAuth can issue opaque (non-JWT) tokens

JWT vs. SAML

AspectJWTSAML
FormatCompact JSON, base64url-encodedVerbose XML
Typical useAPIs, mobile apps, modern SPAsEnterprise single sign-on (SSO)
SizeSmall — fits in headers/URLs easilyLarge — usually posted as a form body

Browser tool vs. CLI / JWT.io

AspectToolAdda (this page)Typical online decoder
Security analysisBuilt-in heuristic score & warningsUsually decode-only
Token insights dashboardYes — size, claims, expiry, verification at a glanceRarely included
Data handling100% client-side, no network calls with your tokenVaries by tool — always check

The complete guide to JSON Web Tokens

What is a JWT?

A JSON Web Token (JWT, pronounced "jot") is an open standard (RFC 7519) for representing a set of claims — small pieces of information about a user or session — as a compact, URL-safe string that can be verified and trusted because it's digitally signed. Instead of a server having to look up a session in a database on every request, a JWT carries its own data and proof of authenticity, which the receiving server can check on its own using math rather than a database round-trip. This makes JWTs a natural fit for stateless APIs, single-page apps, mobile clients, and systems split across many services.

JWT structure: three parts, two dots

Every JWT has the shape header.payload.signature — three base64url-encoded segments joined by periods. Splitting a token on its dots and decoding each segment is exactly what this tool's decoder does the instant you paste a token, with no key required for that first step.

The header, explained

The header is a small JSON object describing the token itself — most importantly alg (the signing algorithm, like HS256 or RS256) and typ (almost always "JWT"). Some tokens also include a kid (key ID) so the verifier knows which of several possible keys to use. The header is what tells a verifier how to check the signature — which is also exactly why a verifier must never blindly trust the alg value from an untrusted token (see the "none" algorithm attack under Security below).

The payload, explained

The payload is where the actual claims live — the data the token is asserting, such as who the user is, what they're allowed to do, and when the token expires. Claims come in three flavours: registered claims (standardized names with defined meaning, like exp and sub), public claims (custom names meant to be collision-resistant and ideally registered in the IANA JWT registry or namespaced with a URI), and private claims (custom names agreed upon between the parties using them, like role or tenant_id). This tool's claims table automatically separates registered claims — with human-readable dates and expiry countdowns — from everything else.

The signature, explained

The signature is computed by taking the encoded header and payload, joining them with a dot, and running that string through a cryptographic signing algorithm (HMAC for symmetric algorithms, or RSA/ECDSA private-key signing for asymmetric ones) using a secret or private key. Anyone can decode the header and payload without any key — but only someone who recomputes this exact signature with the correct secret or key can prove the token is authentic and unmodified. That recomputation and comparison is precisely what this tool's Verify panel does.

JWT vs. session-based authentication

Traditional session authentication issues a random session ID, stores the actual user data server-side (in memory, Redis, or a database), and looks it up on every request. JWTs flip this: the token itself carries the claims, so any server holding the right verification key can validate it without a shared datastore — which is why JWTs scale so naturally across multiple stateless API servers or microservices. The trade-off is revocation: a session can be deleted server-side instantly, while a JWT remains valid until it expires unless you build additional infrastructure (a token blocklist, short expirations plus refresh tokens, or key rotation) to revoke it early.

Base64URL encoding

JWTs use Base64URL rather than standard Base64 — it replaces the + and / characters (which have special meaning in URLs) with - and _, and drops the trailing = padding, making the result safe to embed directly in URLs, cookies, and HTTP headers without escaping. Critically, Base64URL is encoding, not encryption — decoding requires no secret at all, which is why this tool (and any JWT decoder) can show you the header and payload of any token instantly, valid or not.

JWT signing algorithms

The alg header claim determines how a token is signed and verified. This tool supports verification for the algorithm families actually in common use: HS256/384/512 (HMAC with SHA-256/384/512 — symmetric, one shared secret), RS256/384/512 (RSASSA-PKCS1-v1.5 with SHA-256/384/512 — asymmetric, RSA key pair), PS256/384/512 (RSA-PSS — a more modern, provably-secure RSA padding scheme), and ES256/384 (ECDSA over the P-256/P-384 curves — asymmetric, smaller keys and signatures than RSA). A token declaring alg: "none" is explicitly unsigned and must never be accepted by a real verifier — this tool flags it immediately as a critical security issue.

HS256 vs. RS256: which should you use?

HS256 is simplest when a single backend both issues and verifies its own tokens — one secret does both jobs, but that secret must stay confidential everywhere it's used, and anyone who has it can forge valid tokens. RS256 (or ES256) separates signing from verification: a private key signs tokens on one trusted issuer, while any number of other services can verify using only the corresponding public key, which is safe to distribute freely since it can't be used to create new valid signatures. This is why RS256/ES256 are the standard choice for OAuth/OIDC identity providers and any system where multiple independent services need to verify tokens they didn't issue themselves.

How signature verification actually works

Verification recomputes the exact same signing operation the issuer performed — hashing the header-and-payload string with the algorithm named in the header, using the secret (HMAC) or private key (RSA/ECDSA signing on the issuer's side, public key checking on the verifier's side) — and compares the result to the signature segment of the token. If they match, the token's header and payload have not been altered since signing, and (for asymmetric algorithms) came from someone holding the private key. If they don't match — wrong key, wrong algorithm, or tampered content — verification fails, which is exactly the "Invalid signature" result you'll see in the Verify panel.

JWT security fundamentals

The single most important fact about JWTs: the header and payload are encoded, not encrypted. Anyone who intercepts a token — a browser extension, a proxy log, a curious user with dev tools open — can read every claim inside it without any key. Never place passwords, full credit card numbers, or other genuinely secret data in a JWT payload. Separately, verifiers must be coded defensively: never trust the alg header from an incoming token to decide how to verify it (the classic "alg confusion" and "none algorithm" attacks exploit servers that do this), always check exp server-side even though most libraries do this automatically, and prefer asymmetric algorithms (RS/ES) whenever multiple services need to verify tokens they didn't issue.

Expiration and other time-based claims

exp (expiration time) and nbf (not before) are Unix timestamps — whole seconds since January 1, 1970 UTC — that define the window during which a token should be accepted. iat (issued at) records when the token was created and is often used to compute a token's total intended lifetime (exp − iat). This tool converts all three to readable local dates plus a human "in 2 hours" / "3 days ago" countdown, and flags tokens with no exp at all — such tokens never expire by design, which is rarely what you actually want.

Refresh tokens

Because a compromised long-lived JWT is hard to revoke, most real systems issue short-lived access tokens (minutes to a couple of hours) alongside a separate, longer-lived refresh token that's used only to obtain a new access token from the auth server — never sent directly to APIs. This limits how long a stolen access token remains useful, while refresh tokens themselves can be revoked server-side (since redeeming one requires a round-trip to the issuer) even though the access tokens they produce cannot be individually revoked before they expire.

JWT, OAuth 2.0 and OpenID Connect

JWT is a token format; OAuth 2.0 is an authorization protocol for how a user grants an application limited access to their data; OpenID Connect (OIDC) is an identity layer built on top of OAuth 2.0 specifically for authentication. In a typical OIDC flow, the identity provider issues a JWT "ID token" (proving who the user is) and often a JWT or opaque "access token" (proving what the app is allowed to do) — this tool is a natural companion for inspecting exactly those tokens while building or debugging a login flow.

API authentication with JWT

A typical JWT-secured API flow: the client authenticates once (username/password, OAuth, etc.) and receives a signed JWT; the client then sends that token on every subsequent request, almost always in the Authorization: Bearer <token> HTTP header; the API verifies the signature and checks claims like exp, aud (is this token meant for me?) and iss (did I actually issue or trust this token's issuer?) before trusting any of the claims inside to make an authorization decision.

Common JWT mistakes

  • Storing sensitive data in the payload — passwords, full card numbers, or private personal data have no business inside a JWT, since anyone can decode it.
  • Trusting the client-supplied alg header without pinning the expected algorithm server-side, opening the door to algorithm-confusion attacks.
  • No expiration claim, or an expiration so far in the future it's effectively permanent.
  • Using HS256 with a weak, short, or guessable secret — HMAC secrets should be long, random, and generated with a proper tool, not a memorable phrase.
  • Storing JWTs in localStorage in a way that's readable by any injected script (XSS), instead of an HttpOnly cookie where practical.
  • Never rotating signing keys, which turns any eventual key leak into an indefinite compromise.

Debugging JWTs in practice

Most real-world JWT bugs fall into a handful of buckets this tool is built to surface immediately: a token that looks fine but fails verification (usually the wrong secret/key, or a mismatched algorithm between issuer and verifier); a token rejected as expired sooner than expected (check both exp and your server's clock — clock drift between services is a classic culprit); claims missing that your application expects (compare the payload against what your issuing code is supposed to set); and malformed tokens from a copy-paste error (missing a segment, extra whitespace, or truncation) — the decoder reports exactly which segment failed to parse rather than a generic failure.

JWT best practices checklist

  • Always set a short, sensible exp — minutes to a few hours for access tokens, not days or "never."
  • Prefer RS256/ES256 over HS256 whenever more than one service needs to verify tokens.
  • Pin the expected algorithm(s) in verifier code — never derive verification behaviour from the token's own header.
  • Never store secrets, passwords, or highly sensitive personal data in the payload.
  • Use refresh tokens for long-lived sessions instead of long-lived access tokens.
  • Validate aud and iss, not just the signature — a validly signed token from the wrong issuer or meant for a different audience should still be rejected.
  • Rotate signing keys periodically and support multiple valid keys via kid during rotation windows.

Troubleshooting common errors

  • "This does not look like a JWT" — check for missing dots, extra whitespace/newlines, or that you copied the complete token including all three segments.
  • "Invalid signature" — double-check you're using the exact secret/key the token was actually signed with, and that the algorithm matches (HS secrets and RS/ES public keys are not interchangeable).
  • "Invalid header/payload — could not decode" — the base64url segment itself is corrupted, often from a copy-paste that dropped characters or added line breaks.
  • Token "expired" immediately after being issued — check your server's clock is correctly synced (NTP), and confirm exp is in seconds, not milliseconds (a very common off-by-1000 bug).

Summary

A JWT is a signed, self-contained bundle of claims — readable by anyone, but only trustworthy once its signature is verified against the correct key. This tool decodes instantly with no key needed, runs a genuine cryptographic verification when you provide one, and layers on the claim analysis and security warnings a real debugging session actually needs. Paste a token above to get started.

Other browser-based tools that pair well with a JWT / authentication workflow.

Frequently asked questions

Everything developers usually ask before debugging their first JWT.

What is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe token made of three base64url parts separated by dots: header, payload, and signature. It is widely used for authentication and passing claims between services.

How does JWT decoding work?

A JWT's header and payload are split on the dots and base64url-decoded into readable JSON. No key or secret is needed to decode a token — only to verify its signature.

Is decoding the same as verification?

No. Decoding just reads the base64url-encoded header and payload, which anyone can do. Verification cryptographically checks the signature against a secret or public key to confirm the token has not been tampered with.

Is my token uploaded anywhere?

No. Decoding and signature verification both run entirely in your browser using the Web Crypto API. Your token, secret, and keys are never sent to any server.

How do I verify a JWT?

Enter the shared secret for HMAC algorithms (HS256/384/512), or paste a PEM public key for RSA and ECDSA algorithms (RS, PS, ES). The tool recomputes the signature and shows whether it matches.

What is HS256?

HS256 is HMAC using SHA-256 — a symmetric algorithm where the same secret both signs and verifies the token. Both the issuer and verifier must keep that secret private.

What is RS256?

RS256 is RSA signature with SHA-256 — an asymmetric algorithm where a private key signs the token and a separate public key verifies it, so the verifier never needs the private key.

Why is my token expired?

The token's exp (expiration) claim is a Unix timestamp in the past. Once exp has passed, a correctly implemented server should reject the token even if the signature is valid.

What does exp mean?

exp is the expiration time claim — a Unix timestamp (seconds since 1970) after which the token must no longer be accepted.

What does nbf mean?

nbf (not before) is a Unix timestamp before which the token must not be accepted, useful for issuing tokens that only become valid at a future time.

Can I verify RSA signatures?

Yes. RS256/384/512 and PS256/384/512 (RSA-PSS) are both supported — paste the PEM-encoded public key to verify.

Can I use PEM keys?

Yes, paste a standard PEM-formatted public key (starting with -----BEGIN PUBLIC KEY-----) for RSA or ECDSA algorithms.

Is this tool free?

Yes, completely free with no sign-up, no watermark and no usage limits.

Does it work offline?

Once the page has loaded, decoding and verification both work without an internet connection since everything runs locally.

Can I decode malformed JWTs?

The tool will attempt to decode each segment independently and clearly reports which part (header or payload) failed to parse, rather than failing silently.

What happens if verification fails?

You'll see a clear invalid-signature status. Common causes are a wrong secret/key, a token that was edited after signing, or mismatching the algorithm the token actually uses.

Can I export the payload JSON?

Yes, both the header and payload can be copied to your clipboard or downloaded as .json files individually.

Is it browser-based?

Yes, 100%. There is no backend — parsing, decoding and cryptographic verification all happen with JavaScript running locally on your device.

Can beginners use this tool?

Yes. Load the sample token to see a working example, and every claim, warning and status is explained in plain language.

Does it support ES256?

Yes, ES256 and ES384 (ECDSA) are supported for verification using a PEM public key.

What are registered claims?

Registered claims are the standard, predefined JWT payload fields — iss, sub, aud, exp, nbf, iat and jti — recognized and given special handling by this tool and by JWT libraries generally.

How secure is JWT?

A JWT is only as secure as its signature and how the verifier checks it. The header and payload are merely encoded, not encrypted, so nothing secret should ever be stored in one, and the alg field must never be trusted blindly by a verifier.

What is Base64URL?

Base64URL is a variant of Base64 encoding that replaces + and / with - and _ and omits padding, making the output safe to use directly inside URLs and HTTP headers.

Are my secrets stored anywhere?

No. Secrets and keys you enter for verification stay in your browser's memory for the current session only and are never saved, logged, or transmitted.

What browsers are supported?

Any modern browser with Web Crypto API support — recent Chrome, Edge, Firefox and Safari all work, on both desktop and mobile.

Can I generate a new JWT instead of decoding one?

Yes — use ToolAdda's companion JWT Encoder tool to build and sign a new token, then paste it back here to double-check it decodes as expected.

Ready to debug your first token?

No sign-up, no install, no upload — just paste a JWT and see everything instantly.

🔐 Start decoding now