JWT Decoder & Validator→Specialized Version
🎟️

Access Token Decoder

Decode access tokens

Decoding happens in this tab. Nothing is sent to a server — but a JWT is a credential, so avoid pasting production tokens into any online tool.

✓Token is within its validity window

Expires: 3/17/2030, 5:46:40 PM (1294d 22h 29m from now)

HEADERAlgorithm & token type

{
  "alg": "HS256",
  "typ": "at+jwt"
}

PAYLOADData & claims

{
  "iss": "https://auth.example.com",
  "sub": "user_917",
  "aud": [
    "api.example.com"
  ],
  "scope": "profile email",
  "exp": 1900000000,
  "jti": "8f14a2"
}

SIGNATUREVerification hash

HcQr7yMv2NpXsLkTaBdWuEZjRoi9gFsPxYnVbKlD3mA

Claims

ClaimValueMeaning
issregisteredhttps://auth.example.comIssuer — who minted the token
subregistereduser_917Subject — the user or entity it identifies
audregistered["api.example.com"]Audience — who is allowed to accept it
scopeprofile emailGranted scopes
expregistered3/17/2030, 5:46:40 PMExpiration time
jtiregistered8f14a2JWT ID — unique identifier, used to revoke or de-duplicate

Access Token Decoder

Decode API access tokens in JWT format to understand their permissions, scope, and validity. Access tokens authorize requests to protected resources.

Access Token Purpose

FunctionDescription
AuthorizationProves the bearer can access resources
ScopeDefines what actions are permitted
IdentityOften contains user/client information
ExpirationLimits how long access is granted

Access Token Claims

ClaimPurposeExample
subResource owner"user_123"
client_idApplication"my_app"
scopePermissions"read write delete"
audAPI identifier"https://api.example.com"
expExpiration1699900800

Access Token Decoder

``javascript function decodeAccessToken(token) { const parts = token.split('.');

if (parts.length !== 3) { return { format: 'opaque', note: 'Opaque tokens must be validated via introspection endpoint', hint: 'POST to /oauth/introspect with token parameter' }; }

const decode = (s) => JSON.parse(atob(s.replace(/-/g, '+').replace(/_/g, '/'))); const payload = decode(parts[1]);

// Parse scopes const scopes = payload.scope ? payload.scope.split(' ') : payload.scp || [];

// Calculate remaining validity const now = Math.floor(Date.now() / 1000); const remainingSeconds = payload.exp ? payload.exp - now : null;

return { format: 'jwt', subject: payload.sub, clientId: payload.client_id || payload.azp, audience: payload.aud, scopes, permissions: payload.permissions || [], issuedAt: payload.iat ? new Date(payload.iat * 1000) : null, expiresAt: payload.exp ? new Date(payload.exp * 1000) : null, remainingTime: remainingSeconds > 0 ? ${Math.floor(remainingSeconds / 60)} minutes : 'EXPIRED', isExpired: remainingSeconds <= 0 }; } `

Common Scopes by Provider

ProviderScopesPurpose
Googlegmail.readonly, drive.fileGoogle API access
GitHubrepo, user:emailRepository and user access
MicrosoftUser.Read, Mail.SendMicrosoft Graph access
Custom APIread:users, write:postsYour API permissions

Access Token Lifecycle

` 1. Client requests token (authorization code, client credentials, etc.) 2. Auth server issues access token (+ optional refresh token) 3. Client sends token in Authorization header 4. Resource server validates token 5. Token expires → use refresh token for new access token `

The Attacks a Verifier Must Stop

alg: none. A token declaring no algorithm with an empty signature. A library that trusts the header's alg will accept it as valid. Always specify the expected algorithm when verifying rather than reading it from the token.

Algorithm confusion. A token signed with HMAC using the server's *public* RSA key as the secret. If the verifier picks the algorithm from the header, an RS256 verifier can be tricked into running HS256 with a key the attacker already has.

Weak secrets. HS256 with a short or dictionary secret is brute-forceable offline from a single captured token. Use at least 256 bits of real entropy.

No expiry check. exp is a claim, not an enforcement. A library that decodes without verifying, or code that reads claims from a decoded-but-unverified token, accepts expired and forged tokens alike.

`javascript // Specify the algorithm; never trust the header's jwt.verify(token, secret, { algorithms: ['HS256'] }); `

Anyone Can Read the Payload

A JWT is signed, not encrypted. The payload is base64url — readable by anyone holding the token, including the browser it is stored in. Never put anything in it you would not print on a postcard: no passwords, no PII beyond an identifier, no internal keys.

Revocation Is the Hard Part

A signed token is valid until it expires, and there is no way to withdraw one. Options:

ApproachCost
Short expiry (5–15 min) plus refresh tokensStandard; adds a refresh endpoint
A denylist of revoked JTIsReintroduces the state JWTs were meant to avoid
Rotate the signing keyRevokes every token at once
Version claim checked against the user recordA database read per request
If you need immediate revocation for every session, a server-side session is a simpler and more honest choice than a JWT.

Where to Store One

LocationXSS-safeCSRF-safe
localStorageNoYes
sessionStorage`NoYes
Cookie (HttpOnly, Secure, SameSite)YesYes, with SameSite
In-memoryYesYes
An HttpOnly cookie is the safest default. Any token reachable from JavaScript is reachable by any script that gets injected.

Frequently Asked Questions

Where should I send the access token?

Send access tokens in the Authorization header: 'Authorization: Bearer <token>'. Don't put tokens in URLs (logged in server logs), cookies (CSRF vulnerable), or request bodies. The Bearer scheme is standard for OAuth 2.0 and most APIs expect this format.

How long should access tokens last?

Short-lived is more secure—typically 15 minutes to 1 hour. Shorter times limit damage if a token is stolen. Use refresh tokens for longer sessions. Some APIs use longer-lived tokens (24 hours) for simplicity, but this increases risk if tokens are compromised.

What happens when my access token expires?

The API returns 401 Unauthorized. Your app should: 1) Use a refresh token to get a new access token silently, 2) If no refresh token or it's expired, redirect user to re-authenticate. Handle 401s gracefully—queue requests, refresh token, retry requests.

Related Tools

Explore other tools you might find useful:

More JWT Decoder & Validator tools

You might also need