JWT Decoder

JSON Web Tokens are everywhere in modern web development, from API authentication to single sign-on flows, yet debugging them often means pasting tokens into random websites or writing throwaway scripts.

This JWT decoder lets you paste any JWT and instantly see its decoded header, payload, and signature right in your browser with nothing sent to a server.

The tool parses the three Base64URL-encoded segments of the token and displays every claim in a readable format. You can inspect standard registered claims like iss (issuer), sub (subject), aud (audience), exp (expiration time), nbf (not before), and iat (issued at) alongside any custom claims your application adds. Expiration timestamps are automatically converted to human-readable dates so you can tell at a glance whether a token is still valid or has already expired.

Whether you are troubleshooting a 401 error from your API, verifying the claims embedded in an OAuth access token, or teaching yourself how JWTs work for the first time, this decoder gives you immediate visibility into the token structure without installing anything or trusting a third-party server with your credentials.

What Is a JSON Web Token?

A JSON Web Token (JWT, pronounced "jot") is a compact, URL-safe string used to represent claims between two parties. Defined in RFC 7519, JWTs are the dominant token format for stateless authentication in modern web applications. When a user logs in, the server generates a JWT containing identity claims, signs it with a secret or private key, and hands it to the client. The client then sends that token with every subsequent request, typically in the Authorization header, so the server can verify the caller’s identity without maintaining session state.

A JWT consists of three parts separated by dots:

Header.Payload.Signature

Each part is Base64URL-encoded. The header declares the token type and the signing algorithm. The payload carries the claims, which are statements about the user and any additional metadata the application needs. The signature ensures the token has not been tampered with since it was issued.

This three-part structure is what makes JWTs self-contained. The server does not need to look up session data in a database. It simply verifies the signature, checks the expiration, and reads the claims directly from the token. That statelessness is the primary reason JWTs became the standard for API authentication and authorization.

Anatomy of a JWT: Header, Payload, and Signature

Understanding each segment is critical when debugging authentication issues or designing token-based systems.

The Header is a JSON object that typically contains two fields: alg (the signing algorithm, such as HS256 or RS256) and typ (the token type, almost always "JWT"). When decoded, a typical header looks like this:

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "abc123"
}

The kid (key ID) field, when present, tells the verifier which key from a JWKS (JSON Web Key Set) to use for signature validation. This is common in systems that rotate signing keys.

The Payload contains the claims. JWT claims fall into three categories:

  • Registered claims are predefined by the JWT specification and include iss (issuer), sub (subject), aud (audience), exp (expiration time), nbf (not before), iat (issued at), and jti (JWT ID). These are not mandatory but are widely used and recommended.
  • Public claims are defined by the application and registered in the IANA JSON Web Token Claims registry to avoid collisions. Examples include email, name, and preferred_username from the OpenID Connect specification.
  • Private claims are custom claims agreed upon between parties, such as role, permissions, or tenant_id.

A decoded payload might look like:

{
  "sub": "user-4829",
  "name": "Jane Developer",
  "email": "[email protected]",
  "role": "admin",
  "iat": 1711900000,
  "exp": 1711903600
}

The iat and exp values are Unix timestamps (seconds since January 1, 1970). This decoder converts those timestamps into human-readable dates automatically, so you do not need to manually calculate whether the token is expired.

The Signature is created by taking the encoded header, the encoded payload, and a secret or private key, then applying the algorithm specified in the header. For HMAC-based algorithms (HS256), the server and client share the same secret. For RSA-based algorithms (RS256), the server signs with a private key and the client verifies with the corresponding public key. This decoder displays the signature segment but does not verify it, since verification requires the secret or public key that only your server possesses.

Common JWT Signing Algorithms

The algorithm specified in the header determines how the signature is generated and verified. Choosing the right algorithm has significant security implications.

HS256 (HMAC with SHA-256) uses a single shared secret for both signing and verification. It is simple to implement and fast to compute, making it a popular choice for applications where the same server both issues and verifies tokens. The downside is that the secret must be shared with every service that needs to verify tokens, increasing the risk of key compromise in distributed systems.

RS256 (RSA Signature with SHA-256) uses an asymmetric key pair. The issuer signs with a private key, and verifiers use the corresponding public key. This is the preferred algorithm for systems where multiple services need to verify tokens but only one service issues them, such as identity providers and microservice architectures. The public key can be distributed freely without compromising security.

ES256 (ECDSA with P-256 and SHA-256) is an elliptic curve algorithm that provides equivalent security to RS256 with much shorter keys and signatures. A 256-bit ECDSA key offers roughly the same security as a 3072-bit RSA key. ES256 is increasingly popular for performance-sensitive applications and mobile platforms.

EdDSA (Edwards-curve Digital Signature Algorithm) using Ed25519 is the newest option, offering high performance and strong security guarantees. It is gaining adoption in modern authentication systems.

The none algorithm exists in the specification but should never be accepted in production. Accepting unsigned tokens is a well-known vulnerability that has led to real-world exploits. If your decoder shows "alg": "none" in a token from your system, that is a critical security issue to investigate immediately.

How to Use JWTs for Authentication

The most common JWT workflow in web applications follows this pattern:

  1. The user submits credentials (username and password) to the authentication endpoint.
  2. The server validates the credentials, generates a JWT with appropriate claims, and returns it to the client.
  3. The client stores the token (typically in memory or a secure HTTP-only cookie) and includes it in the Authorization header of subsequent API requests as a Bearer token.
  4. The server extracts the token from the header, verifies the signature, checks the expiration, and reads the claims to authorize the request.

This flow eliminates the need for server-side session storage, which is a major advantage for horizontally scaled systems. Each server instance can independently verify tokens without consulting a shared session store.

However, statelessness comes with tradeoffs. The biggest is that JWTs cannot be easily revoked once issued. If a user logs out or their permissions change, the token remains valid until it expires. Common mitigations include keeping token lifetimes short (15 minutes for access tokens is typical), using refresh tokens with longer lifetimes stored securely on the server side, and maintaining a token blocklist for critical revocations.

JWT Security Best Practices

Tokens carry sensitive identity information, so handling them correctly is essential.

Keep tokens short-lived. Access tokens should expire in minutes, not hours or days. Short lifetimes limit the window of exposure if a token is leaked. Pair short-lived access tokens with longer-lived refresh tokens that are stored securely and can be revoked.

Never store tokens in localStorage. Browser localStorage is accessible to any JavaScript running on the page, making it vulnerable to cross-site scripting (XSS) attacks. Prefer HTTP-only, Secure, SameSite cookies for browser-based applications. For single-page applications that must use tokens directly, store them in memory and accept that they will not persist across page reloads.

Validate all claims on the server. Always verify the signature, check that exp has not passed, confirm the iss matches your expected issuer, and validate the aud matches your application. Skipping any of these checks opens the door to token abuse.

Use strong signing keys. For HMAC algorithms, use a key of at least 256 bits generated from a cryptographically secure random source. For RSA, use at least 2048-bit keys (3072-bit or 4096-bit preferred). Rotate keys periodically and use the kid header to manage key transitions.

Never put sensitive data in the payload. The payload is encoded, not encrypted. Anyone with the token can decode it and read the claims. Never include passwords, credit card numbers, or other secrets in JWT claims. If you need encrypted tokens, use JWE (JSON Web Encryption) instead of JWS (JSON Web Signature).

Debugging JWT Issues

When authentication breaks, the JWT is usually the first place to look. Here are the most common issues developers encounter and how to diagnose them.

Token expired. Decode the token and check the exp claim. If it is in the past, the token has expired. This is normal behavior, not a bug. The fix is to use your refresh token to obtain a new access token, or re-authenticate. If tokens are expiring too quickly, consider adjusting the lifetime on your auth server.

Invalid signature. This usually means the token was signed with a different key than the one the server is using for verification. Common causes include key rotation where the server is using a new key but the token was signed with the old one, environment mismatches where the development and production environments use different secrets, or the token being modified in transit.

Wrong audience or issuer. If your server validates aud and iss claims (and it should), a mismatch will cause rejection. This often happens when tokens issued for one environment (staging) are used in another (production), or when a token issued for one microservice is sent to a different one.

Clock skew. Token validation depends on system clocks. If the server clock is slightly behind the issuer clock, a token might appear expired even though it was just issued. Most JWT libraries accept a small clock skew tolerance (usually a few seconds) to handle this. Use our Unix Timestamp Converter to compare timestamps.

This decoder helps with all of these scenarios by giving you instant visibility into every claim in the token. Paste the token, check the timestamps, verify the algorithm, and read the claims to pinpoint exactly where the problem lies.

Frequently Asked Questions

Is it safe to paste my JWT into an online decoder?

This decoder runs entirely in your browser. The token is never sent to any server. That said, JWTs contain identity claims that could be sensitive, so avoid pasting production tokens into tools that transmit data to a backend. Always verify that a decoder operates client-side before using it with real tokens.

Can a JWT be decoded without the secret key?

Yes. The header and payload of a JWT are only Base64URL-encoded, not encrypted. Anyone with the token can decode and read the claims. The secret key is only needed to verify the signature, which confirms the token has not been tampered with. This is why you should never put sensitive information like passwords in JWT claims.

What does the exp claim mean in a JWT?

The exp (expiration time) claim is a Unix timestamp indicating when the token becomes invalid. After this time, the server should reject the token. It is expressed in seconds since January 1, 1970 (UTC). This decoder automatically converts the timestamp to a human-readable date for easy inspection.

What is the difference between HS256 and RS256?

HS256 uses a shared secret for both signing and verification (symmetric). RS256 uses a private key for signing and a public key for verification (asymmetric). RS256 is preferred for distributed systems where multiple services verify tokens but only one issues them, because the public key can be shared freely without compromising security.

How long should a JWT access token last?

For access tokens, 15 minutes is a common recommendation. Short lifetimes limit exposure if a token is leaked. Pair short access tokens with longer-lived refresh tokens (hours or days) that can be stored securely and revoked if needed. The right balance depends on your security requirements and user experience goals.

Can JWTs be revoked?

Not natively. Once issued, a JWT is valid until it expires. To revoke tokens before expiration, implement a server-side blocklist that checks each token against a list of revoked token IDs (the jti claim). Alternatively, keep access token lifetimes very short so that revocation of the refresh token effectively locks the user out within minutes.

What happens if someone modifies a JWT payload?

If any part of the token is modified after signing, the signature verification will fail. The server will reject the token because the signature no longer matches the header and payload. This is the fundamental security guarantee of JWTs. Without the signing key, an attacker cannot forge a valid signature for a modified payload.

What is the difference between JWT, JWS, and JWE?

JWT is the general term for the token format. JWS (JSON Web Signature) is a JWT that is signed but not encrypted, which is the most common type. JWE (JSON Web Encryption) is a JWT that is encrypted so the claims cannot be read without the decryption key. Most implementations use JWS because the claims do not need to be secret, only tamper-proof.

Data accurate as of: March 2026