The Three Parts

The header encodes a JSON object like {"alg":"HS256","typ":"JWT"} specifying the signing algorithm. The payload encodes the claims: user ID, roles, expiration time, and custom claims. The signature is the HMAC or RSA signature over header.payload. Only the signature provides security — header and payload are readable by anyone.

Decoding the Payload

Decoding a JWT payload requires only Base64 decoding — no key needed. Paste any JWT into jwt.io or split on dots and Base64-decode the second segment. You'll see all claims in plaintext. This is intentional: JWT consumers need to read claims without having the signing key.

What Claims You Can Trust

After Base64 decoding the payload, validate the 'exp' (expiration) claim before trusting any other claim. Then verify the signature using the public key or shared secret. Only after successful signature verification are the claims trustworthy.

JWE for Actual Confidentiality

If JWT claims must be kept confidential, use JSON Web Encryption (JWE) rather than plain JWT. JWE encrypts the payload so only parties with the decryption key can read it. The resulting structure is still Base64 URL-encoded but the payload is ciphertext.

Key Takeaway

JWT Base64 encoding makes the structure readable and portable — security comes entirely from signature verification. Decode payloads freely but never trust unverified claims.