DevToolsForYou
Auth & Security

How to Parse a JWT

A practical guide to reading and decoding JSON Web Tokens — understand the three-part structure, decode the header and payload, and know what to check before trusting a token.

2 min readUpdated Apr 11, 2026

What is a JWT?

A JSON Web Token (JWT) is a compact, URL-safe string used to represent claims between two parties. You'll encounter them most often as bearer tokens in Authorization headers, as the payload inside cookies, or embedded in OAuth 2.0 flows. A JWT carries information — like a user ID, roles, or an expiry time — in a self-contained format so the receiver doesn't need to look it up in a database.

The three-part structure

Every JWT has exactly three parts separated by dots: a header, a payload, and a signature. Each part is independently base64url-encoded, which means you can decode the header and payload without any secret.

text
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMzYwMDB9
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Decoding the header

The header tells you which algorithm was used to sign the token. Base64url-decode the first segment and you get a JSON object. Common algorithms are HS256 (HMAC with SHA-256, symmetric) and RS256 (RSA with SHA-256, asymmetric).

json
// Raw first segment
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

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

Decoding the payload

The payload (second segment) contains the actual claims. Standard registered claims include sub (subject), iat (issued at), exp (expiry), iss (issuer), and aud (audience). You can add any custom claims your application needs.

json
// Raw second segment
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMzYwMDB9

// Decoded
{
  "sub": "1234567890",
  "name": "Jane Doe",
  "iat": 1700000000,
  "exp": 1700036000
}

Decoding manually in JavaScript

You can decode the header and payload in any environment without a library. The only gotcha is that base64url uses - and _ instead of + and /.

javascript
function decodeJwtPayload(token) {
  const [, payloadB64] = token.split(".");
  // base64url → base64
  const b64 = payloadB64.replace(/-/g, "+").replace(/_/g, "/");
  return JSON.parse(atob(b64));
}

const payload = decodeJwtPayload("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyXzEyMyJ9.sig");
console.log(payload.sub); // "user_123"

What to check before trusting a token

Decoding is not the same as verifying. Before acting on claims you must: (1) verify the signature using the issuer's secret or public key, (2) confirm the exp claim has not passed, (3) check the iss and aud claims match your expected values. Skipping signature verification is a common and serious security mistake — it lets an attacker forge any claims they like.

Frequently asked questions

Can I decode a JWT without the secret?

Yes — the header and payload are just base64url encoded, so you can decode them anywhere. But you cannot verify the signature without the secret or public key, which means you cannot trust the contents.

Why does my JWT decoder show garbled text?

You may have pasted only part of the token or copied it with extra whitespace. A valid JWT always has exactly two dots and three non-empty segments.

What is the difference between HS256 and RS256?

HS256 uses a shared secret — both the signer and verifier need the same key. RS256 uses an asymmetric key pair: the issuer signs with a private key and anyone can verify with the corresponding public key, which is useful when multiple services need to verify tokens.

Related cheatsheetsAll cheatsheets →
Related guidesAll guides →