jsonsql.dev100% client-side

JWT Decoder

Decode and inspect JSON Web Tokens instantly in your browser

Loading JWT Decoder...

How to decode a JWT token online

jsonsql.dev decodes JSON Web Tokens instantly in your browser. No data is sent to any server — your token stays on your machine.

Paste your JWT — copy the JWT from your API response, Authorization header, or cookie and paste it into the input field above. The "Bearer " prefix is stripped automatically.

View decoded parts — the header, payload, and signature are displayed immediately. Claims like exp, iat, and sub are shown in human-readable format.

Copy what you need — click Copy on the header or payload section to copy the decoded JSON to your clipboard.

Example

Input JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Decoded header:

{
  "alg": "HS256",
  "typ": "JWT"
}

Decoded payload:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

What is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe token format used for securely transmitting information between parties. It consists of three Base64URL-encoded parts separated by dots: header, payload, and signature.

The header specifies the signing algorithm (e.g., HS256, RS256). The payload contains claims — statements about the user and metadata. The signature verifies the token has not been tampered with.

Common JWT claims

  • iss (Issuer) — who issued the token
  • sub (Subject) — the user or entity the token represents
  • aud (Audience) — intended recipient of the token
  • exp (Expiration) — Unix timestamp when the token expires
  • nbf (Not Before) — token is not valid before this time
  • iat (Issued At) — when the token was created
  • jti (JWT ID) — unique identifier for the token

Features

  • Decode JWT header and payload to formatted JSON
  • Color-coded token parts: header (red), payload (purple), signature (cyan)
  • Human-readable display of common claims (iss, sub, aud, exp, nbf, iat, jti)
  • Expiration status: shows if the token is expired or when it expires
  • Syntax highlighting for decoded JSON
  • Automatically strips "Bearer " prefix from pasted tokens
  • Copy header or payload individually
  • Dark and light theme support
  • Works offline — no internet needed after the page loads
  • 100% client-side — no data is sent to any server

JWT Decoder vs other tools

Featurejsonsql.devjwt.iojwt.ms
Client-side onlyYesYesYes
Color-coded partsYesYesNo
Expiration statusYesNoYes
Claims explanationYesNoYes
Syntax highlightingYesYesNo
Dark modeYesNoNo
No adsYesNoYes
Works offlineYesNoNo

JWT structure explained

A JWT consists of three Base64URL-encoded parts separated by dots: the header (algorithm and type), the payload (claims about the user), and the signature (cryptographic proof of authenticity).

Header

The header is a JSON object that describes the token's type and the cryptographic algorithm used to sign it. The two standard fields are:

  • alg — the signing algorithm. Common values: HS256 (HMAC with SHA-256), RS256 (RSA with SHA-256), ES256 (ECDSA with P-256 curve). HS256 uses a shared secret; RS256 and ES256 use public/private key pairs.
  • typ — the token type, almost always "JWT".
{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "my-key-id"
}

Some headers include a kid (Key ID) field that tells the server which key to use for signature verification — useful when rotating keys.

Payload

The payload contains claims — statements about the user and metadata. Claims fall into three categories:

  • Registered claims — standardized by RFC 7519: iss (issuer), sub (subject), aud (audience), exp (expiration), nbf (not before), iat (issued at), jti (JWT ID).
  • Public claims — defined in the IANA JSON Web Token Claims registry or using collision-resistant names (e.g., URIs). Examples: email, name, preferred_username.
  • Private claims — custom claims agreed upon between the issuer and consumer, such as role, tenant_id, or permissions.
{
  "iss": "https://auth.example.com",
  "sub": "user-42",
  "aud": "https://api.example.com",
  "exp": 1893456000,
  "iat": 1672531200,
  "role": "admin",
  "permissions": ["read", "write"]
}

Signature

The signature ensures the token has not been tampered with. It is computed by:

  1. Concatenating the Base64URL-encoded header and payload with a dot: base64url(header) + "." + base64url(payload)
  2. Signing the result with the specified algorithm:
    • HMAC (HS256/HS384/HS512): HMAC-SHA(secret, data) — uses a single shared secret key.
    • RSA (RS256/RS384/RS512): RSA-SHA(privateKey, data) — signs with a private key, verified with the corresponding public key.
    • ECDSA (ES256/ES384/ES512): ECDSA-SHA(privateKey, data) — elliptic curve variant, smaller keys than RSA for equivalent security.
  3. Base64URL-encoding the resulting bytes to produce the third part of the token.

The signature proves the token was issued by a trusted party and has not been modified. Without the signing key, you cannot create a valid signature — but anyone can decode the header and payload.

Common JWT claims reference

ClaimNameMeaningExample valueCommon usage
issIssuerIdentifies the principal that issued the token"https://auth.example.com"Verify token origin; reject tokens from unknown issuers
subSubjectIdentifies the user or entity the token represents"user-42"Map token to a specific user account in your system
audAudienceIntended recipient(s) of the token"https://api.example.com"Prevent token misuse across different services
expExpirationUnix timestamp after which the token must be rejected1893456000 (2030-01-01)Enforce token lifetime; reject expired tokens even if signature is valid
nbfNot BeforeUnix timestamp before which the token must not be accepted1672531200 (2023-01-01)Delay token activation; useful for pre-issued tokens
iatIssued AtUnix timestamp when the token was created1672531200 (2023-01-01)Determine token age; enforce maximum age policies
jtiJWT IDUnique identifier for the token"550e8400-e29b-41d4-a716"Prevent token replay attacks by tracking used token IDs

The exp claim is a Unix timestamp indicating when the token expires. Tokens should be rejected after this time, even if the signature is valid. Most JWT libraries handle this automatically, but clock skew between servers can cause issues — a common tolerance is 30-60 seconds.

JWT security best practices

JWT payloads are Base64URL-encoded, not encrypted — anyone can decode and read them. Never store passwords, credit card numbers, or other secrets in a JWT.

  • Never store sensitive data in the payload. The payload is only encoded, not encrypted. Anyone who intercepts the token can read every claim. If you need to transmit sensitive data, use JWE (JSON Web Encryption) instead of JWS.
  • Always verify signatures server-side. Decoding a JWT and trusting its claims without verifying the signature is a critical vulnerability. An attacker could modify the payload and forge claims like "role": "admin".
  • Use short expiration times. Access tokens should expire in 5-15 minutes. Use refresh tokens (stored securely, ideally in httpOnly cookies) to obtain new access tokens. Short-lived tokens limit the damage window if a token is compromised.
  • Reject the "none" algorithm. Some JWT libraries have historically accepted "alg": "none", which means no signature is required. Always validate the algorithm against an allowlist of expected values.
  • Use asymmetric algorithms for distributed systems. RS256 or ES256 let services verify tokens with a public key without needing access to the signing secret. This is essential for microservices architectures.
  • Understand decoding vs. verifying. Decoding extracts header and payload from the Base64URL-encoded token — anyone can do this, no key required. Verifying checks the cryptographic signature to ensure the token was not tampered with and was issued by a trusted party. This tool only decodes; always verify server-side.

JWT debugging workflow

When a JWT-related issue arises in your application, follow this systematic debugging workflow:

  1. Get the token from your browser. Open Chrome DevTools (F12), then:
    • From cookies: Go to Application tab, expand Cookies in the sidebar, and find the cookie containing your JWT.
    • From localStorage/sessionStorage: Go to Application tab, expand Local Storage or Session Storage, and look for keys like access_token or id_token.
    • From a network request: Go to Network tab, find an API request, click it, and look for the Authorization: Bearer eyJ... header.
  2. Paste the token into the decoder. Copy the full token (or the entire Bearer eyJ... string — the prefix is stripped automatically) and paste it into the input field above.
  3. Check the expiration. Look at the expiration badge next to the Payload header. If it says "Expired X ago", the token has expired and needs to be refreshed. Compare the exp and iat timestamps to understand the token's intended lifetime.
  4. Verify the claims. Check that iss matches your expected issuer, aud matches your API, and sub is the correct user. Mismatched claims are a common cause of 401/403 errors.
  5. Check the algorithm. Ensure the alg in the header matches what your server expects. A mismatch (e.g., sending an HS256 token to a server expecting RS256) will cause signature verification to fail.

Common issues and fixes:

  • Expired token — refresh the token using your refresh token endpoint or re-authenticate.
  • Wrong audience (aud) — ensure the token was issued for the correct API. Multi-tenant systems often have different audience values per environment.
  • Clock skew — if tokens expire immediately after being issued, check that server clocks are synchronized (NTP). Most libraries allow a small leeway (30-60 seconds).
  • Invalid signature — the token may have been tampered with, or the server is using a different signing key than expected. Check key rotation settings.

JWT vs session cookies vs API keys

Different authentication mechanisms suit different architectures. Here is how JWT compares to traditional session cookies and API keys:

FeatureJWTSession cookiesAPI keys
StateStateless — all data in the tokenStateful — session data on the serverStateless — key identifies the client
ScalabilityExcellent — no server-side storage neededRequires shared session store (Redis, DB) across serversExcellent — simple lookup
RevocationHard — must use blocklists or short expiryEasy — delete session from serverEasy — delete key from database
PayloadContains user data and claimsSession ID only — data on serverNo payload — just an identifier
Cross-domainWorks easily via Authorization headerRequires CORS + SameSite configurationWorks via header or query parameter
Security riskToken theft gives access until expirySession hijacking, CSRF attacksKey leakage gives permanent access
Best forSPAs, mobile apps, microservicesTraditional server-rendered web appsServer-to-server, third-party integrations
Token sizeLarge (hundreds of bytes to several KB)Small (session ID, ~32 bytes)Small (~32-64 bytes)

When to use which: Use JWTs for stateless authentication in SPAs and microservices where horizontal scaling matters. Use session cookies for server-rendered applications where easy revocation is important. Use API keys for server-to-server communication and third-party API access where user context is not needed.

Related tools

Frequently asked questions

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 like user ID, expiration, etc.), and the signature (cryptographic proof of integrity).

What is the difference between decoding and verifying a JWT?

Decoding extracts the header and payload from the Base64URL-encoded token — anyone can do this without a key. Verifying checks the signature to confirm the token was not tampered with, which requires the signing key.

How do I check if a JWT token is expired?

Decode the token and look at the exp (expiration) claim in the payload. It is a Unix timestamp in seconds. If the current time is past that timestamp, the token is expired. This tool automatically shows the expiration status with a colored badge — green for valid, red for expired — along with a human-readable time difference.

What is the difference between HS256 and RS256?

HS256 (HMAC with SHA-256) uses a single shared secret key for both signing and verification. Both the issuer and verifier must know the same secret. RS256 (RSA with SHA-256) uses a public/private key pair — the issuer signs with the private key, and verifiers use the public key. RS256 is preferred for distributed systems because verifiers do not need access to the signing secret.

Does this work with JWE (encrypted tokens)?

No. This tool decodes JWS (signed) tokens only. JWE tokens are encrypted and cannot be decoded without the decryption key.

Can a JWT be tampered with?

Anyone can modify the Base64URL-encoded payload of a JWT, but the signature will no longer be valid. A properly implemented server will reject a token with a mismatched signature. The risk arises when servers fail to verify signatures, accept the "none" algorithm, or confuse symmetric and asymmetric keys. Always verify signatures server-side with a trusted library.