What is a JSON Web Token?

A JSON Web Token (JWT) is an open standard (RFC 7519) for securely transmitting information between parties as a compact, self-contained string. JWTs are the dominant format for modern API authentication — used by Auth0, Firebase Auth, AWS Cognito, and virtually every OAuth 2.0 implementation.

The key property that makes JWTs useful is that they are self-contained: the token carries all the information needed to verify its validity and identify the user, without requiring the server to query a session database on every request. A server can validate a JWT by checking its cryptographic signature alone.

This tool decodes the header and payload sections of any JWT so you can inspect the claims, check the algorithm, and verify expiry times during development and debugging. It does not perform signature verification — that requires your secret key and must be done in your application code.

JWT structure: three parts explained

Every JWT is a string of three Base64url-encoded sections joined by dots: header.payload.signature. Base64url is a URL-safe variant of Base64 that replaces + with - and / with _, with no padding characters.

Header

A JSON object declaring the token type and signing algorithm. Example: {"alg":"HS256","typ":"JWT"}. The "alg" field is critical — it tells the verification library which algorithm to use. Always validate that "alg" matches what your application expects. Never accept tokens with "alg":"none".

algSigning algorithm: HS256, RS256, ES256, etc.
typToken type — always "JWT"
kidKey ID — identifies which key to use for verification (optional)
Payload

A JSON object containing claims — statements about the user and metadata about the token. Claims are divided into registered (standard, like exp and sub), public (well-known names), and private (application-specific). The payload is encoded, not encrypted — anyone can decode and read it.

subSubject — who the token refers to (user ID)
issIssuer — who issued the token (your auth server URL)
audAudience — who the token is intended for (your API)
expExpiration time — Unix timestamp after which token is invalid
iatIssued at — Unix timestamp when the token was created
nbfNot before — Unix timestamp before which token is not valid
jtiJWT ID — unique identifier for this token (for revocation)
Signature

The cryptographic proof that the header and payload were not altered. Computed as: HMAC-SHA256(base64url(header) + "." + base64url(payload), secret) for HS256, or an RSA/ECDSA signature for asymmetric algorithms. Only the signature section is secret — the header and payload are just encoded.

JWT signing algorithms compared

The algorithm in the JWT header determines how the signature is created and verified. Choosing the wrong algorithm for your architecture is one of the most common JWT security mistakes:

AlgorithmTypeKeyBest for
HS256 / HS512Symmetric (HMAC)Same secret signs and verifiesSingle-server apps where only one party needs to verify
RS256 / RS512Asymmetric (RSA)Private key signs, public key verifiesMultiple services need to verify — share public key only
ES256 / ES512Asymmetric (ECDSA)Private key signs, public key verifiesLike RS256 but smaller signatures, better for mobile
PS256 / PS512Asymmetric (RSA-PSS)Private key signs, public key verifiesHigh-security scenarios; FIPS-compliant

JWT security best practices

Always validate the algorithm

Never let the client choose the algorithm. Hardcode the expected algorithm in your verification code. The "alg:none" attack exploits libraries that accept tokens without a signature if the header declares "none" as the algorithm. Explicitly reject tokens with unexpected algorithms.

Keep access tokens short-lived

Access tokens should expire in 15 minutes to 1 hour. Use refresh tokens for longer sessions. Short expiry limits the window of exploitation if a token is stolen from a log, a cache, or a compromised client.

Store tokens securely on the client

For browser apps: store access tokens in memory (a JavaScript variable), not localStorage. Use HttpOnly, Secure, SameSite=Strict cookies for refresh tokens — they are inaccessible to JavaScript and immune to XSS. localStorage and sessionStorage are readable by any script on the page.

Never put sensitive data in the payload

JWT payloads are encoded, not encrypted. Anyone with the token can decode and read the payload. Store only non-sensitive identifiers (user ID, role, email). Never put passwords, payment details, or PII that does not need to be in the token.

Implement token revocation for critical operations

Stateless JWTs cannot be revoked before expiry by default. For logout, password change, and account takeover recovery, maintain a token deny-list (Redis is ideal) keyed on jti (JWT ID). Check the deny-list on every request for sensitive operations. Use short expiry as a fallback for less critical tokens.

Validate all standard claims

Always verify: exp (reject expired tokens), nbf (reject tokens used before their valid period), iss (reject tokens from unknown issuers), and aud (reject tokens not intended for your service). Missing these checks makes the signature verification insufficient — a valid signature does not mean a token is currently usable.

JWT vs session tokens — when to use each

JWTs and server-side sessions each have clear use cases. The "JWTs are always better" narrative is incorrect — the right choice depends on your architecture.

Use JWTs when…
  • You have multiple services that need to verify the token independently
  • You want stateless servers with no shared session store
  • Your tokens are short-lived (15–60 minutes)
  • You are building a public API consumed by third-party clients
  • You use OAuth 2.0 or OpenID Connect
Use sessions when…
  • You need immediate token revocation (logout, suspicious activity)
  • Your application is a traditional server-rendered web app
  • You want simpler security model — server controls all session state
  • Token size is a concern (session IDs are much smaller than JWTs)
  • You are storing sensitive data that should never leave the server

Related security tools

When working with JWTs, you often need these companion tools:

FAQ

Common questions

Is it safe to paste my JWT into this tool?

Yes — all decoding happens entirely in your browser. No part of your token is sent to any server. However, be careful about pasting live production tokens with sensitive payload data into any online tool as a general practice.

Does this tool verify the JWT signature?

No. This tool decodes and displays the header and payload, but does not verify the signature. Signature verification requires your secret key or public key and must be done server-side. Never trust a JWT whose signature has not been verified by your application.

What are the three parts of a JWT?

A JWT has three Base64url-encoded parts separated by dots: the Header (algorithm and token type), the Payload (claims — data about the user and token), and the Signature (a cryptographic hash of the header and payload using your secret key). Only the signature is secret; the header and payload are just encoded, not encrypted.

What does "exp" mean in the JWT payload?

"exp" is the expiration claim — a Unix timestamp (seconds since 1970-01-01) after which the token must be rejected. This tool highlights expired tokens in red. Other time claims include "iat" (issued at) and "nbf" (not before — the earliest time the token is valid).

What is the difference between JWT and a session token?

A session token is an opaque random string stored server-side — the server looks it up in a database to find the associated user. A JWT is a self-contained token — the server can verify and read the user data directly from the token without a database lookup. JWTs are stateless (no server storage needed) but cannot be revoked without extra infrastructure.

What signing algorithms can a JWT use?

Common algorithms include: HS256/HS384/HS512 (HMAC-SHA — symmetric, uses a shared secret), RS256/RS384/RS512 (RSA — asymmetric, uses a private key to sign and public key to verify), ES256/ES384/ES512 (ECDSA — asymmetric, smaller signatures than RSA), and PS256/PS384/PS512 (RSA-PSS). The algorithm is specified in the JWT header's "alg" field. Never accept tokens signed with "alg: none".

Can I decode a JWT without the secret key?

Yes — the header and payload are only Base64url-encoded, not encrypted. Anyone can decode them. This is why you should never store sensitive data like passwords or payment details in a JWT payload. The secret key is only required to verify the signature (to confirm the token was not tampered with).

How long should a JWT access token be valid?

Access tokens should have short expiry times — typically 15 minutes to 1 hour. Short-lived tokens limit the damage if a token is stolen. Use refresh tokens (longer-lived, stored securely) to issue new access tokens without requiring the user to log in again. Never set access token expiry to days or indefinite.

What is a JWT refresh token?

A refresh token is a separate, longer-lived credential (hours to days) used to obtain new access tokens when the access token expires. Refresh tokens should be stored securely (HttpOnly cookies, not localStorage), rotated on each use, and invalidated on logout. This architecture gives you stateless access tokens with the ability to revoke sessions.

More in Security