JWT Decoder
Decode and inspect JSON Web Tokens (JWT) to view header, payload, and signature.
Enter JWT Token
Header
{
"alg": "HS256",
"typ": "JWT"
}Algorithm
HS256
Type
JWT
Payload
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022,
"exp": 1735689600
}Signature
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cNote: This tool only decodes the JWT. It does not verify the signature. Never trust a JWT without proper server-side signature verification.
What Is a JSON Web Token (JWT)?
A JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. JWTs are widely used in modern web applications to implement stateless authentication and secure information exchange between clients and servers. Because a JWT is self-contained, the server does not need to store session data in a database — all necessary information travels inside the token itself.
JWT became an open standard defined in RFC 7519 and is now foundational to OAuth 2.0 authorization flows, OpenID Connect identity layers, and countless REST API authentication schemes. You will encounter JWTs in virtually every technology stack, from Node.js microservices to mobile apps, single-page applications, and serverless functions.
The key benefit of a JWT over a traditional opaque session token is transparency with integrity. Any party in possession of the token can read the header and payload without a secret key, but they cannot forge or alter the token without invalidating the cryptographic signature. This makes JWTs particularly well-suited for stateless, distributed architectures where the server that issues a token might be different from the server that later validates it.
Common real-world uses of JWTs include:
- Authentication: After a user logs in, the server issues a JWT. Subsequent requests include the JWT so the server can identify the user without a session lookup.
- Authorization: JWTs carry role or permission claims that downstream services can check without contacting a central auth server.
- Information exchange: Signed JWTs let parties exchange verified data over insecure channels.
- Single sign-on (SSO): A single JWT can authenticate a user across multiple independent domains or services.
JWT Structure: Header, Payload, and Signature
Every JWT consists of exactly three Base64URL-encoded parts separated by dots (.), giving it the familiar three-segment appearance you see when you paste a token into a JWT decoder. The three parts are the header, the payload, and the signature.
Header
The header is a JSON object that describes the token's metadata. It almost always contains two fields: alg, which names the signing algorithm (for example HS256, RS256, or ES256), and typ, which is set to the literal string JWT. The header JSON is then Base64URL-encoded to produce the first segment of the token. Common algorithms include HMAC-SHA256 (symmetric, shared secret), RSA-SHA256 (asymmetric, public/private key pair), and ECDSA P-256 (elliptic-curve variant of RSA).
Payload
The payload is a JSON object containing the claims — statements about the subject and any additional metadata. The JWT specification defines several registered claim names that carry standardized meanings:
- sub (subject): Identifies the principal that is the subject of the JWT, typically a user ID.
- iss (issuer): Identifies the party that issued the token.
- aud (audience): Identifies the recipients for whom the token is intended.
- iat (issued at): Unix timestamp (seconds since epoch) when the token was issued.
- exp (expiration time): Unix timestamp after which the token must not be accepted.
- nbf (not before): Unix timestamp before which the token must not be accepted.
- jti (JWT ID): A unique identifier for the token to prevent replay attacks.
In addition to registered claims, applications freely add public and private claims such as name, email, role, or any application-specific field.
Signature
The signature is computed by taking the encoded header, a dot, and the encoded payload, then signing that string with the algorithm and secret specified in the header. For HS256, the operation is HMAC-SHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret). The result is Base64URL-encoded and appended as the third segment. Any modification to the header or payload will produce a different signature, immediately revealing tampering.
JWT Decoding Formula
Where:
- header= Base64URL-encoded JSON object containing alg and typ
- payload= Base64URL-encoded JSON object containing claims (sub, iat, exp, etc.)
- signature= Third segment — raw Base64URL-encoded cryptographic signature (not decoded to JSON)
- Base64URLdecode= Replace '-' with '+', replace '_' with '/', pad to multiple of 4, then atob() and percent-decode UTF-8
- exp= Unix epoch seconds × 1000 converted to a JavaScript Date for expiration check
- iat= Unix epoch seconds × 1000 converted to a JavaScript Date for issued-at display
- nbf= Unix epoch seconds × 1000 converted to a JavaScript Date for not-before display
How This JWT Decoder Works
This free online JWT decoder takes a token string, splits it on the . character, and processes each of the three resulting segments. The decoder performs a pure client-side Base64URL decode of the header and payload — no data is ever sent to any server, making this tool safe to use with real tokens in a development or debugging context.
The Base64URL decoding process used by the tool follows these exact steps:
- Replace every
-character with+and every_character with/to convert Base64URL encoding back to standard Base64. - Pad the resulting string with
=characters until its length is a multiple of 4, because standard Base64 requires this. - Call the browser's built-in
atob()function to decode the Base64 string to a binary string. - Percent-encode each character as a two-digit hex sequence, then pass the result through
decodeURIComponent()to correctly handle multi-byte UTF-8 characters, including emoji and accented letters. - Parse the resulting string as JSON to produce the header or payload object.
After decoding, the tool extracts well-known timestamp claims from the payload. For the exp (expiration) claim, it multiplies the Unix epoch seconds value by 1000 to obtain a JavaScript-compatible millisecond timestamp, then compares it to new Date() to determine whether the token is currently valid or has expired. The same millisecond conversion applies to iat (issued at) and nbf (not before) for human-readable display. The signature segment is displayed as-is because verifying it requires the secret key or public key — information the decoder intentionally does not request.
The tool provides instant, real-time decoding as you type or paste tokens. If the token does not contain exactly three dot-separated segments, an error message is shown immediately. This makes the JWT decoder ideal for rapid debugging of authentication issues, inspecting tokens returned by identity providers, and confirming that claims like sub, role, or email carry the expected values.
Security Considerations When Decoding JWTs
Understanding what a JWT decoder can and cannot do is critical for anyone working with token-based authentication. A JWT decoder reads and displays the header and payload, but it does not verify the signature. This distinction has major security implications that developers must keep in mind.
Because the header and payload are only Base64URL-encoded — not encrypted — anyone who intercepts a JWT can decode it and read its claims. This means JWTs are not confidential by default. Never store sensitive data such as passwords, credit card numbers, or personally identifiable information in a JWT payload unless you are also using JSON Web Encryption (JWE) to encrypt the entire token.
The security of a JWT rests entirely on the signature. A server-side JWT validation library will:
- Re-compute the expected signature from the received header and payload using the known secret or public key.
- Compare that expected signature to the signature segment in constant time to prevent timing attacks.
- Reject the token if the signatures do not match — this would indicate tampering or a forged token.
- Check the
expclaim to ensure the token has not expired. - Optionally check
iss,aud, andnbfclaims for additional validation.
A particularly dangerous mistake is accepting the algorithm specified in the token's own header without whitelisting allowed algorithms on the server. Early JWT libraries had a vulnerability where an attacker could set alg: "none" in the header, causing some libraries to skip signature verification entirely. Always configure your JWT library to accept only the specific algorithm(s) your system uses.
When using this decoder tool, treat decoded payloads as informational only. Never make authorization decisions based solely on a client-side decoded JWT — always perform full server-side signature verification using a trusted library before granting access to protected resources.
Common JWT Claims Reference
The JWT specification defines a compact vocabulary of registered claim names that carry standardized meanings across all implementations. Understanding these claims helps you inspect tokens efficiently and debug authentication issues quickly. The table below summarizes the most frequently encountered claims, their data types, and how this decoder tool presents them.
| Claim | Full Name | Type | Description |
|---|---|---|---|
sub |
Subject | String | Unique identifier for the user or entity the token describes. |
iss |
Issuer | String / URI | Identifies the authorization server that issued the token. |
aud |
Audience | String / Array | The intended recipients; servers must reject tokens not addressed to them. |
iat |
Issued At | NumericDate | Unix epoch seconds when the token was created; shown as a human-readable date. |
exp |
Expiration | NumericDate | Unix epoch seconds after which the token is invalid; decoder shows valid/expired status. |
nbf |
Not Before | NumericDate | Unix epoch seconds before which the token must not be accepted. |
jti |
JWT ID | String | Unique token identifier; used to prevent replay attacks via a server-side blocklist. |
alg |
Algorithm (header) | String | Signing algorithm; common values are HS256, RS256, ES256, PS256. |
typ |
Type (header) | String | Token type; almost always the literal string JWT. |
Beyond registered claims, applications routinely add custom claims such as role, email, name, permissions, and tenant_id. These appear in the payload alongside the standard claims and are displayed in full by this decoder. When debugging access control issues, checking these custom claims is often the first step to understanding why a user is or is not authorized for a particular resource.
JWT vs Session Tokens: When to Use Each
JWT-based authentication and traditional server-side session tokens represent two fundamentally different philosophies for managing user identity. Choosing the right approach for your application requires understanding the trade-offs each brings.
Traditional session tokens are opaque random strings stored in a server-side session store (a database, Redis cache, or memory). When a request arrives, the server looks up the token in the store to retrieve user data. This approach is simple, supports instant revocation (just delete the session record), and keeps sensitive data on the server. The drawback is that it introduces a centralized store that must be shared across all server instances in a distributed deployment, adding latency and a single point of failure.
JWTs are self-contained. All user information travels in the token, so any server can validate a request without a database call — only the cryptographic verification is needed. This makes JWTs excellent for microservices, multi-region deployments, and API gateways. However, JWTs cannot be revoked before their expiration time without maintaining a blocklist, which reintroduces shared state. Short expiration windows (15 minutes to 1 hour) combined with refresh token rotation are the standard mitigation.
Use JWTs when you need stateless, horizontally scalable authentication, when multiple independent services share an identity provider, or when you need to pass verifiable claims across trust boundaries. Prefer server-side sessions when you need instant revocation, when all traffic passes through a single application tier, or when compliance requirements prohibit storing user attributes in a client-readable format.
Worked Examples
Decoding a Standard Authentication Token
Problem:
Decode the header and payload of a JWT issued after user login: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3MzU2ODk2MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Solution Steps:
- 1Split the token on '.' to get three segments: header segment = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', payload segment = 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3MzU2ODk2MDB9', and the signature segment.
- 2Base64URL-decode the header segment (replace '-' with '+', '_' with '/', pad to multiple of 4, then atob + decodeURIComponent): result is the JSON object { "alg": "HS256", "typ": "JWT" }. Algorithm is HMAC-SHA256, type is JWT.
- 3Base64URL-decode the payload segment the same way: result is { "sub": "1234567890", "name": "John Doe", "iat": 1516239022, "exp": 1735689600 }.
- 4Convert the exp claim: 1735689600 × 1000 = 1735689600000 ms. new Date(1735689600000) = January 1, 2025. Compare to the current date to determine validity.
- 5Convert the iat claim: 1516239022 × 1000 = 1516239022000 ms. new Date(1516239022000) = January 18, 2018 — the date the token was issued.
Result:
Header: alg=HS256, typ=JWT. Payload: subject='1234567890', name='John Doe', issued January 18 2018, expires January 1 2025. Since today is June 2026, the token is expired.
Inspecting a Role-Based Authorization Token
Problem:
A backend API returns a JWT whose payload contains custom claims. After decoding, the raw payload JSON is: { "sub": "user_789", "iss": "https://auth.example.com", "aud": "api.example.com", "role": "admin", "iat": 1717200000, "exp": 1717203600 }. Determine the token's validity window.
Solution Steps:
- 1The iat claim is 1717200000. Multiply by 1000: 1717200000000 ms. new Date(1717200000000) is June 1, 2024 at 00:00:00 UTC — the moment the token was issued.
- 2The exp claim is 1717203600. Multiply by 1000: 1717203600000 ms. new Date(1717203600000) is June 1, 2024 at 01:00:00 UTC — the token is valid for exactly 3600 seconds (one hour).
- 3The role claim 'admin' is a custom application claim. It is displayed in the payload section and can be used by the frontend to show or hide admin UI elements — but backend enforcement must re-verify the token's signature.
- 4The iss claim 'https://auth.example.com' identifies the authorization server. The aud claim 'api.example.com' means only the API server at that domain should accept the token.
Result:
Token was valid from June 1 2024 00:00 UTC to June 1 2024 01:00 UTC (one-hour window). Custom claim role='admin'. Because today is June 2026, the token is expired.
Decoding a Token with a Not-Before Claim
Problem:
A token has iat=1720000000, nbf=1720003600, and exp=1720010800. Determine the full validity window and when the token first becomes usable.
Solution Steps:
- 1Convert iat: 1720000000 × 1000 ms. new Date(1720000000000) = July 3, 2024 at approximately 10:26:40 UTC. This is when the token was created and signed.
- 2Convert nbf (not before): 1720003600 × 1000 ms. new Date(1720003600000) = July 3, 2024 at 11:26:40 UTC. The token was issued but deliberately cannot be used until one hour after creation — a common pattern for scheduling access.
- 3Convert exp: 1720010800 × 1000 ms. new Date(1720010800000) = July 3, 2024 at 13:26:40 UTC. The token expires three hours after the nbf, giving a two-hour usable window from 11:26 to 13:26 UTC.
- 4The decoder displays all three dates: Issued At, Not Before, and Expiration. If the current time is between nbf and exp, the token should be accepted by a properly implemented server.
Result:
Token issued at 10:26 UTC, usable from 11:26 UTC, expired at 13:26 UTC on July 3 2024. Usable window is exactly 2 hours. As of June 2026, the token is expired.
Tips & Best Practices
- ✓Always inspect the alg field in the header first — if it shows 'none', the token has no signature and should be rejected by a properly configured server.
- ✓Convert exp, iat, and nbf Unix timestamps manually if needed: multiply the claim value by 1000 and pass it to new Date() in any browser console.
- ✓Keep JWT expiration times short (15–60 minutes) for access tokens and implement refresh token rotation to reduce the window of exposure if a token is stolen.
- ✓Never store sensitive data like passwords or payment information in a JWT payload — the payload is only Base64URL-encoded, not encrypted, and anyone with the token can read it.
- ✓Use the aud (audience) claim to prevent token misuse: if a token issued for your mobile app is stolen, a properly configured API server will reject it if the aud value does not match.
- ✓When debugging authentication failures, compare the iss claim in the token to the issuer URL configured in your server's JWT validation middleware — a mismatch is a common source of errors.
- ✓Prefer RS256 or ES256 over HS256 for APIs that are consumed by multiple independent services, since asymmetric algorithms let you share the public key freely without exposing the signing secret.
- ✓Use the jti (JWT ID) claim plus a server-side blocklist to implement logout before a token's natural expiration, which is otherwise impossible with stateless JWTs.
Frequently Asked Questions
Sources & References
Last updated: 2026-06-05
Help us improve!
How would you rate the JWT Decoder?
Editorial Note
MyCalcBuddy Editorial Team
This page is maintained as an educational calculator reference.
Formula Source: Standard Mathematical References
by Various