How to Read a JWT Payload Without Trusting It
A JSON Web Token, usually called a JWT, looks like a long string of letters, numbers, dots, and dashes. You may see one in a login response, in an authorization header, or in a browser’s storage while debugging an app. It is tempting to decode it, read the contents, and treat what you see as proof of who the user is. That temptation is exactly where mistakes happen.
Decoding a JWT payload tells you what the token claims. It does not tell you whether those claims are true. A payload can be decoded by anyone, because the encoding is not encryption. It can also be copied, changed, and re-encoded by anyone, unless the token is properly verified. If you skip verification, you are trusting data that an attacker can forge in seconds.
This guide explains how to read a JWT payload safely for inspection and debugging, what each part means, and why decoding is never the same as verifying. It includes a worked example with common claims, plus the limitations and questions that matter most when you work with tokens.
What a JWT Is Made Of
A JWT has three parts, separated by dots: a header, a payload, and a signature. Written in general form, it looks like this:
header.payload.signature
The header usually says what type of token it is and which signing algorithm was used. The payload contains claims, which are statements about the user, the token, or the session. The signature is used to check whether the header and payload have been changed since the token was issued. Together, the three parts form one compact string that can be passed in a header or stored as text.
Each part is encoded with a URL-safe version of Base64. Base64 is an encoding, not encryption. Encoding changes how data is represented so it can travel safely in a URL or header. It does not hide the data from anyone who can see the token. That is a crucial distinction. If a JWT contains sensitive information, anyone who gets the token can decode it and read that information. For that reason, tokens should not carry passwords, private personal details, or anything you would not want exposed if the token leaked.
How to Read a Payload Step by Step
Use these steps only for inspection, learning, or debugging a token you are allowed to examine. Do not use the decoded payload to make an access decision unless your server has verified the signature first.
- Confirm you are allowed to inspect the token. Only decode tokens from your own account, your own test environment, or a system where you have permission to debug. Do not decode or share tokens that belong to other people.
- Split the token by dots. A well-formed JWT has exactly two dots, which divide it into three segments. If there are more or fewer parts, the token is malformed or it is not a JWT at all.
- Take the middle segment. The first segment is the header, the second is the payload, and the third is the signature. For reading claims, you need the second segment.
- Base64 decode the payload segment. Use a trusted decoder or a standard library in your language. Remember that JWTs use Base64URL encoding, which replaces two characters used in standard Base64 and omits padding. Many decoders handle that automatically, but some require you to add padding or convert characters first.
- Read the result as JSON. The decoded payload should be JSON text, usually an object with keys and values. If it is not valid JSON, the token may be corrupted, truncated, or encoded in a different way.
- Check the claim names, but do not trust them yet. Look for common claims such as subject, issued-at, and expiration, and note what they say. Then stop. Verification is a separate step that must happen on the server before the claims are used.
For decoding, use a well-known tool or library rather than pasting a real production token into a random website. A token is a credential. If you paste it into an untrusted site, you may have given that site access to your account. In a test environment, use a test token with no real access, or use a local decoder that does not send the token anywhere.
Worked Example: A Typical Payload
Suppose you have a JWT whose payload, after Base64 decoding, looks like this:
{
"sub": "12345",
"name": "Test User",
"iat": 1700000000,
"exp": 1700003600
}
Here is what each field means in this example.
The sub claim stands for subject. It is meant to identify the user or entity the token is about. In this example, the subject is the string 12345. That value is only meaningful inside the system that issued the token. It does not prove that the person presenting the token is that user, unless the signature has been verified.
The name claim is an example of a custom or descriptive claim. It says Test User. That is a readable label, not a security proof. Anyone can create a token that claims any name, so a name in a decoded payload should never be treated as authentication on its own.
The iat claim stands for issued at. It is a numeric date, counted as seconds since January 1, 1970, in Coordinated Universal Time. In this example, 1700000000 is the time the token was issued. It helps you understand whether the token is old or new.
The exp claim stands for expiration. It is also a numeric date in the same format. In this example, 1700003600 is one hour after the issued-at time, because 3600 seconds equals one hour. After that time, the token should be treated as expired, even if the payload still decodes correctly.
Reading this payload tells you what the token claims: that it is about subject 12345, that it was issued at a certain time, and that it expires an hour later. It does not tell you whether the token was really issued by your server, whether the payload was changed, or whether the token was stolen. Those questions can only be answered by verification.
Decoding Is Not Verifying
This is the most important idea in the whole guide. Decoding is reading. Verifying is checking. They are different jobs, and only verification makes a token trustworthy.
Verification means checking the signature using the correct key and algorithm, confirming that the token has not expired, checking that it was issued by the expected issuer if your system uses one, and checking that it is being used for the expected audience and purpose. It also means rejecting tokens that use the none algorithm, which means no signature, and rejecting tokens where the signature does not match the header and payload.
An attacker can create a new payload, encode it, and present it as a JWT. If the server only decodes the payload and never checks the signature, it will accept the forged claims. That is why client-side decoding, browser code, or a simple decode step in an API must never be treated as proof. Verification must happen on the server, with a secret or public key that the client does not control.
Think of it like reading a letter. Anyone can write a letter that says they are an authorized manager. Reading the letter tells you what it claims. Checking the signature, the sender, and the official record tells you whether to believe it. A JWT payload is the letter. Verification is the check.
What to Look For When Inspecting a Payload
When you inspect a payload for debugging, look for a few common issues. First, check whether the expiration time has passed. An expired token should not be accepted, even if it looks otherwise correct. Second, check whether the issued-at time is in the future, which may suggest a clock problem or a forged token. Third, check whether the subject or user ID matches what you expect for the test account you are using.
Fourth, look for unexpected claims or missing claims. If your system expects a role, a scope, or an audience claim, and it is missing, that may explain why access is denied. Fifth, check whether the payload contains sensitive data that should not be there. If it does, that is a design problem to raise with the team, because every holder of the token can read it.
Finally, check the header as well, even though the focus here is the payload. The header should name an algorithm your system expects. If the header says none, or names an algorithm you do not use, treat the token with suspicion and do not trust it without proper verification.
Common Mistakes to Avoid
One common mistake is trusting a payload in browser code. Browser code can be changed by the user, so it cannot be a security boundary. Another mistake is storing a token in a place where it can be stolen, then assuming that decoding is safe because the payload looks normal. A token that looks normal can still be stolen or forged.
Another mistake is ignoring expiration. A token that decodes correctly is not automatically valid. If it is expired, it should be rejected. A further mistake is accepting tokens from any issuer. If your server accepts tokens from a key or issuer you do not control, an attacker may be able to create a valid-looking token from another system.
A final mistake is sharing real tokens while asking for help. Do not post a production token in a chat, a forum, or a bug report. It may still be valid and may grant access to your account. If you need help, use a test token, remove the signature, or describe the structure without sharing the full credential.
Limitations
Reading a payload has clear limits. It cannot prove who sent the token, it cannot prove that the payload was not changed, and it cannot prove that the token is still valid. It can only show you the claims as they appear in the token you hold.
Decoding also cannot tell you whether the token was revoked. Some systems keep a list of revoked tokens or use short lifetimes and refresh tokens to limit risk. A decoded payload will not show that information unless the system adds it. You need server-side checks for revocation and expiry.
Finally, this guide covers inspection, not implementation. Building secure token verification requires careful key management, correct algorithm checks, clock handling, and error handling. If you are building authentication for a real system, use a well-maintained library and follow the documentation for your platform, rather than writing verification from scratch.
Frequently Asked Questions
Can I read a JWT payload without a special tool?
Yes. You can split the token by dots and Base64 decode the middle segment with a standard decoder or library. The result should be JSON. Remember that reading it does not make it trustworthy.
Why can anyone decode a JWT?
Because Base64 is an encoding, not encryption. It changes the representation of the data so it can travel safely, but it does not hide the data. Anyone who has the token can decode the header and payload.
What does it mean if a token has no signature?
A token with no signature, or with an algorithm of none, provides no proof that it was issued by a trusted party. It should not be trusted for access decisions. Secure systems should reject unsigned tokens.
Should I put private data in a JWT payload?
No. Avoid putting passwords, sensitive personal details, or anything you would not want exposed if the token leaked. Keep payloads small and limited to the claims the system needs.
To read a JWT payload, split the token by dots, Base64 decode the middle segment, and read the JSON claims. To trust it, verify the signature on the server, check expiration, and confirm the issuer and audience. Decoding shows you what a token claims. Verification shows you whether those claims deserve trust. Never confuse the two, and never trust an unsigned or unverified payload.
Try a Tool
Free, in your browser — no sign-up.
Related Articles
How to Tell If a Link Is Safe Before You Click It
Learn how to tell if a link is safe before you click it. Hover to preview, check the domain, treat shorteners with…
Read article →How to Spot a Phishing Email Before You Click
Learn how to spot a phishing email before you click: check the sender, urgency, and links, hover before clicking, skip attachments, and…
Read article →How to Choose a Password Manager (Without Overthinking It)
Learn how to choose a password manager without overthinking it: vault, master password, 2FA, and a simple setup that keeps every account…
Read article →