Free JWT Decoder
Decode and inspect JSON Web Tokens · header, payload, claims and expiration.
Header
Payload
Signature
About JWTs
JSON Web Tokens (JWTs) are a compact way to represent claims between two parties. They consist of three parts: a header (algorithm and type), a payload (claims like issuer, expiration, subject), and a signature. This tool decodes the header and payload but does not verify signatures · for that, you need the signing secret or public key. All decoding happens in your browser; your token is never sent anywhere.
A Short History of JSON Web Tokens
The JSON Web Token (JWT) was standardised as RFC 7519 in May 2015 by Michael B. Jones (Microsoft), John Bradley (Ping Identity), and Nat Sakimura (NRI) under the IETF JOSE Working Group. It was the culmination of half a decade of work: the first JWT internet-draft appeared in December 2010, growing out of SAML 2.0 (2005)'s heavyweight XML-based assertion format and the felt need for something lighter that browsers could parse natively. The breakthrough was choosing JSON over XML and base64url over PEM: a JWT could fit in a URL query string or an Authorization: Bearer header. The whole JOSE family shipped as a coordinated set: RFC 7515 (JWS) for signing, RFC 7516 (JWE) for encryption, RFC 7517 (JWK) for the key format, RFC 7518 (JWA) for algorithm identifiers, and RFC 7519 (JWT) for the claims layer, all on the same day in May 2015. Adoption was instant. OAuth 2.0 (RFC 6749, 2012) had standardised access tokens but left their format opaque; the industry chose JWT. OpenID Connect (December 2014, OpenID Foundation) made JWT mandatory for ID tokens. By 2017 every major identity provider (Auth0, Okta, Azure AD, AWS Cognito, Google Identity, Firebase Auth) issued JWTs as their native session format. JWT.io, the decoder website that Auth0 launched in 2014, became the de facto JWT debugging tool and helped cement the format's developer mindshare. Two security incidents shaped the modern threat model: Tim McLean's 2015 disclosure of the alg: none bypass and the HS/RS algorithm-confusion attack, and CVE-2022-21449 (April 2022), Neil Madden's «Psychic Signatures» bug in Java 15-18's ECDSA verifier. Both led to library-default hardening: most modern libraries now refuse alg: none outright and pin the expected algorithm rather than reading it from the token header.
The Anatomy of a JWT
- Three base64url-encoded segments. A JWT is the string
header.payload.signature: three segments separated by dots, each base64url-encoded. RFC 7519 calls this the JWT Compact Serialization. The whole thing fits in a URL or HTTP header; that compactness was the design goal that distinguished JWT from XML-based predecessors like SAML. - Header. A small JSON object usually containing two fields:
alg(the signing algorithm, e.g. HS256, RS256, ES256) andtyp(almost always «JWT»). Optional fields includekid(a key identifier used for key rotation) andcty(content type for nested tokens). The header tells the verifier how to validate the signature; never trust it alone, always pin the expected algorithm server-side. - Payload. A JSON object of claims, key-value assertions about a subject. RFC 7519 §4.1 reserves seven standard claims:
iss(issuer),sub(subject),aud(audience),exp(expiration),nbf(not-before),iat(issued-at), andjti(unique JWT ID). Issuers add custom claims freely. The payload is signed but not encrypted: anyone with the token can read it. - Signature. The cryptographic proof that the header and payload have not been tampered with. The signing input is the literal string
base64url(header) + "." + base64url(payload); the signature itself is then base64url-encoded as the third segment. Verification requires the symmetric secret (HS*) or the asymmetric public key (RS*, ES*, PS*, EdDSA) and must always happen on a trusted server. - base64url, not base64. JWT segments use the URL-safe base64 variant from RFC 4648 §5: character 62 is
-instead of+, character 63 is_instead of/, and the trailing=padding is stripped. JavaScript's built-inatob()only handles standard base64, so JWT decoders translate the alphabet and re-pad before decoding. - NumericDate: seconds, not milliseconds. RFC 7519 defines
exp,nbf, andiatas «the number of seconds from 1970-01-01T00:00:00Z UTC». JavaScript'sDate.now()returns milliseconds, so a common bug is anexpthree orders of magnitude too large, producing a token that «expires» around the year 53,000. Always useMath.floor(Date.now() / 1000)when minting tokens.
Where JWTs Are Used in Practice
- OAuth 2.0 access tokens. RFC 6749 left the access-token format opaque, but in practice the industry standardised on JWT. Auth0, Okta, Azure AD, AWS Cognito, and Google Identity all issue JWT access tokens by default. The Bearer token in your
Authorizationheader is almost always a JWT. - OpenID Connect ID tokens. OIDC (December 2014) mandates JWT for its
id_token. Theid_tokencarries identity claims about the authenticated user (sub,email,name,picture) and is consumed by the relying party rather than passed onward. This is the primary mechanism behind «Sign in with Google», «Sign in with Apple», and equivalent flows. - API authentication. Stateless REST APIs adopt JWT because it removes the need for a server-side session store: the API trusts whatever the signature verifies. Stripe-style API keys remain common for server-to-server traffic, but for user-scoped APIs, the
Authorization: Bearer <jwt>pattern is now the default. - Microservice-to-microservice auth. A user-scoped JWT minted at the API edge is forwarded through internal service-to-service calls, letting each service trust the original authentication without re-authenticating. The pattern is sometimes called «token translation»: the edge gateway exchanges an opaque session for a short-lived JWT scoped to the downstream call.
- Single-page application sessions. SPAs (React, Vue, Angular) historically stored access tokens in
localStoragefor convenience. Modern guidance (OWASP, Auth0) is to keep access tokens in memory and refresh tokens inHttpOnly + Secure + SameSite=Strictcookies, becauselocalStorageis readable by any XSS that lands on the page. - Mobile app sessions. iOS and Android apps store access tokens in the platform Keychain or Keystore. The token is sent as
Authorization: Beareron every backend call. Refresh tokens are rotated on every use, and the access token's shortexp(typically 5-15 minutes) is the primary defence against stolen-device replay.
Standards and Security Milestones
- RFC 7519 (JWT, May 2015). The base specification. Defines the JWT Compact Serialization, the seven standard registered claims (
iss,sub,aud,exp,nbf,iat,jti), and the NumericDate format. Authors: Michael B. Jones, John Bradley, Nat Sakimura. - RFC 7515 (JWS, May 2015). JSON Web Signature. The signed-wrapper format that almost everyone informally calls «JWT»: three base64url segments joined by dots. JWS supports both compact and JSON Serialization forms; JWT only uses the compact form.
- RFC 7516 (JWE, May 2015). JSON Web Encryption. The encrypted variant with five segments (header, encrypted key, IV, ciphertext, authentication tag). Use JWE, not JWS, when the payload must be confidential, not merely tamper-evident.
- RFC 7517 (JWK, May 2015). JSON Web Key. The JSON representation of cryptographic keys. The JWKS endpoint (
/.well-known/jwks.json) publishes a JSON Web Key Set, the modern mechanism for zero-downtime key rotation: verifiers look up keys bykid. - RFC 7518 (JWA, May 2015). JSON Web Algorithms. The registry of
algidentifiers: HS256/384/512 (HMAC), RS256/384/512 (RSASSA-PKCS1-v1_5), ES256/384/512 (ECDSA), PS256/384/512 (RSASSA-PSS), EdDSA (Ed25519/Ed448), and the (intentionally rarely-used)none. - The
alg: nonebypass (Tim McLean, 2015). RFC 7518 listsnoneas a valid algorithm value for unsecured contexts. Naive verifiers would accept a token with the header rewritten to{"alg":"none"}and an empty signature, letting an attacker forge any payload. Modern libraries refusenoneby default; the spec itself states verifiers «MUST NOT accept Unsecured JWSs by default». - HS/RS algorithm-confusion attack (Tim McLean, 2015). If a verifier picks the algorithm from the token header instead of pinning it, an attacker can rewrite the header to
HS256and sign the token using the server's RSA public key as the HMAC secret. The library sees HS256, treats the configured RSA public key as a symmetric secret, and the signature checks out. Mitigation: pin the expected algorithm out-of-band; never derive it from the token. - CVE-2022-21449 «Psychic Signatures» (Neil Madden, April 2022). Java 15-18's ECDSA verifier did not check that the signature's
randsvalues were non-zero, meaning a literal all-zero signature was accepted as valid. JWTs signed with ES256/384/512 on affected JVMs could be forged with a blank signature. Patched in Oracle's April 2022 Critical Patch Update.
More frequently asked questions
Why does this tool not verify the signature?
Verification needs a secret (HMAC) or public key (RSA / ECDSA / EdDSA). Pasting a production HMAC secret into any website is a credential leak in itself, even on a tool that swears it does not transmit anything. Verification belongs on a server you control. The decoder's job is to make the contents readable so you can see what your verifier should be checking.
Is it safe to paste real production tokens here?
Decoding happens entirely in your browser. The token is not sent over the network, written to any log, or stored anywhere. That said, a JWT often is a credential: anyone holding an unexpired access token can act as the user. The community convention is «treat a production JWT like a session cookie»: prefer test tokens when you can, and rotate any real token you have shared anywhere outside the browser session that minted it.
Where should I store a JWT in the browser?
The two common patterns each have a tradeoff. localStorage is convenient but readable by any successful XSS attack on the page. Cookies with HttpOnly are invisible to JavaScript so XSS cannot read them, but they need SameSite=Strict or SameSite=Lax to avoid CSRF. The current best practice: short-lived access tokens in a JavaScript variable (memory only) plus a long-lived refresh token in an HttpOnly + Secure + SameSite=Strict cookie scoped to the refresh endpoint, rotated on every use.
What does the kid field in the header do?
It identifies which key signed the token. Modern identity providers publish their public keys at a /.well-known/jwks.json endpoint as a JWK Set (RFC 7517); the verifier looks up the key whose kid matches the token's header. This is what makes zero-downtime key rotation possible: both old and new keys can sit in the JWKS during the grace period.
Can I revoke a JWT once it has been issued?
Not natively. A signed JWT is valid until its exp claim; that statelessness is the format's headline property. Workarounds: keep access tokens short (5-15 minutes) paired with a revocable refresh token; maintain a server-side deny list of revoked jti values; rotate the signing key (which invalidates every outstanding token signed with it). Each option re-introduces some statefulness; that's the trade.
Is decoding a token the same as decrypting it?
No. Decoding reverses base64url back to JSON: anyone can do it, and that is the point. Decrypting requires a key and only applies to JSON Web Encryption (JWE, RFC 7516), which is the encrypted variant of the JOSE family. Most tokens you see in the wild are JWS (signed but not encrypted), so decoding is enough to read them.
Related Tools
Hash Generator
Generate MD5, SHA-1, SHA-256, SHA-384, and SHA-512 hashes from text or files.
Base64 Encoder / Decoder
Encode or decode Base64 strings and files. Supports UTF-8 text and drag & drop files.
Text Encryption
Encrypt and decrypt text with AES-256-GCM. 100% client-side · your data never leaves your browser.