JWT Structure in OAuth 2.0
A plain-English tour of the three-part, tamper-evident token format that powers modern access tokens and identity tokens.
Think about a wax seal on an old-fashioned letter. Anyone can read the letter itself once it is open — the words are not secret — but the unbroken wax seal proves the letter really came from the person whose signet ring pressed it, and that nobody quietly altered the contents after it was sealed. A JWT, pronounced “jot” and short for JSON Web Token, works on a strikingly similar idea. It is a compact, easy-to-read piece of text that carries information about a user or a permission grant, wrapped in a tamper-evident seal that lets anyone receiving it confirm it has not been altered since it was created. This tutorial opens up a JWT, piece by piece, to show exactly how that seal works.
1What Is a JWT, and Where Does It Fit Into OAuth 2.0?
Before looking inside a JWT, it helps to understand the gap it fills within the broader OAuth 2.0 picture.
Earlier tutorials in this series explained how OAuth 2.0 hands out access tokens and refresh tokens after a user approves a request. Those tutorials deliberately left one detail open: what does an access token actually look like on the inside? OAuth 2.0 itself does not require any particular token format — a token can be a completely random, meaningless string that only the Authorization Server understands, known as an “opaque token.” A JWT is a popular, standardized alternative format that many Authorization Servers choose instead, because it can carry readable information directly inside itself.
An opaque token is like a coat-check ticket with a random number on it — the ticket itself tells you nothing, and the coat-check counter has to look up its own private records to know whose coat it belongs to. A JWT is more like a boarding pass that already has your name, seat number, and flight details printed directly on it, so any airline gate agent can read the essential facts immediately, without calling back to a central booking database.
Within OAuth 2.0 and its companion identity standard, JWTs are commonly used both as access tokens (proving what a Client is allowed to do) and as ID tokens (proving who the user is), even though these two uses carry different information inside them.
The key idea to hold onto throughout this tutorial is that a JWT is not encrypted or secret by default. Its contents can be read by anyone who gets hold of it, in the same way anyone can read an unsealed letter once it is opened. What a JWT guarantees instead is integrity: proof that whatever is written inside has not been quietly changed since the moment it was created and signed.
2The Three Parts of a JWT
Every JWT, without exception, is built from exactly three sections, joined together with a period character.
If you were to look at a JWT written out as plain text, it would appear as three chunks of jumbled-looking characters, separated by two dots, in the pattern “first-part.second-part.third-part.” Each of these three chunks has a specific, well-defined job.
Header
A small block of metadata describing the token itself — mainly which signing algorithm was used and what type of token this is.
Payload
The actual content — the “claims” — such as who the token is about, who issued it, what it permits, and when it expires.
Signature
A cryptographic seal computed from the header and payload together, used to detect any tampering after the token was created.
flowchart LR
subgraph JWT["A Single JWT String"]
H["Header\n(algorithm + token type)"] --> P["Payload\n(claims about the user or grant)"]
P --> S["Signature\n(proves nothing was changed)"]
end
Picture a sealed exam answer booklet. The cover page (header) states which exam and grading rules apply. The inside pages (payload) contain the actual answers. The wax seal across the back cover (signature) proves nobody swapped out a page after the booklet left the exam hall.
3How the Parts Are Encoded
The jumbled-looking text in each section is not encrypted — it is simply encoded in a way that is safe to place inside a web address or an HTTP header.
Both the header and the payload start out as ordinary, human-readable structured data — essentially a small set of labeled facts, similar to a short form with field names and values. Before being placed into the token, each of these two sections is run through a standard, entirely reversible encoding process called Base64URL encoding. This encoding does not hide or protect the content in any meaningful way; it exists purely to turn the data into a compact set of letters, numbers, and a couple of safe symbols that will not break when placed inside a URL or a network header.
Anyone can take the header or payload section of a JWT and decode it back into readable form in a fraction of a second, using nothing more than a basic decoding tool. A JWT should never be assumed to keep its contents secret from anyone who receives it.
Base64URL encoding is like writing a note in a simple substitution cipher that swaps each letter for a symbol using a publicly known chart taped to the wall. Anyone with the chart, which is to say literally anyone, can instantly translate it back. It changes the note’s appearance, not its secrecy.
Because of this, a golden rule follows naturally: never place a genuinely sensitive secret, such as a raw password, directly inside a JWT’s payload, since anyone who obtains the token can read it in seconds. JWTs are meant to carry claims that are safe to be seen by their intended recipients, protected against tampering rather than protected against reading.
4Inside the Header
The header is deliberately small — usually just a couple of fields describing the token itself.
alg (Algorithm)
Names which cryptographic algorithm was used to create the signature, such as a widely used HMAC-based algorithm or a public-key-based algorithm.
typ (Type)
States the overall token type, almost always simply indicating that this is a JWT, which helps software correctly recognize and parse it.
kid (Key ID)
An optional identifier pointing to which specific signing key, among several the Authorization Server may rotate through, was used for this particular token.
The “kid” field deserves a moment of attention, because it solves a very practical problem. Authorization Servers periodically rotate their signing keys for security hygiene, much like periodically changing the combination on a safe. When multiple keys might be valid at once during a rotation period, the “kid” field tells the token’s recipient exactly which key to fetch and use when checking the signature, rather than needing to guess or try every available key.
5Inside the Payload: Understanding Claims
The payload is where the actual useful information lives, organized as a set of individual facts called “claims.”
A claim is simply one labeled fact inside the payload, similar to a single filled-in field on a form, such as “issued by” or “expires at.” Some claim names are standardized and mean the same thing across virtually every system that uses JWTs, which makes tokens from different companies still somewhat predictable to read and validate.
| Claim | Full Name | What It Represents |
|---|---|---|
| iss | Issuer | Which Authorization Server created and signed this token. |
| sub | Subject | Who or what this token is about, usually a unique user identifier. |
| aud | Audience | Which Resource Server or API this token is intended to be used with. |
| exp | Expiration Time | The exact moment after which this token must no longer be accepted. |
| iat | Issued At | The exact moment the token was originally created. |
| nbf | Not Before | An optional moment before which the token should not yet be accepted, even if otherwise valid. |
| scope | Scope | A space-separated list of permissions this token grants, matching the OAuth 2.0 scopes concept. |
Beyond the standardized claims above, an Authorization Server is free to add its own additional custom claims to the payload, such as a user’s role, department, or account tier, as long as it clearly documents what those extra fields mean.
Think of the payload as a printed conference badge. Standard fields like your name and company appear in the same spot on every attendee’s badge, in a familiar format organizers everywhere recognize. But an individual conference might also print custom extras, like a colored dot marking which sessions you registered for — useful information specific to that one event.
6How the Signature Proves Nothing Was Changed
This chapter explains the actual mechanics behind the tamper-evident seal, without requiring any background in cryptography.
When the Authorization Server creates a JWT, it takes the already-encoded header and payload, combines them, and runs that combination through a mathematical signing process using a secret or private key that only the Authorization Server possesses. The output of that process is the third and final section of the token: the signature. Crucially, this signature is mathematically tied to the exact contents of the header and payload used to create it.
sequenceDiagram
participant A as Authorization Server
participant C as Client / Resource Server
A->>A: 1. Build header and payload
A->>A: 2. Sign header+payload using a secret/private key
A->>C: 3. Send complete JWT (header.payload.signature)
C->>C: 4. Recompute the signature using the known public/shared key
C->>C: 5. Compare recomputed signature to the one in the token
Note over C: Match = trustworthy and unaltered.\nMismatch = reject the token.
When a Resource Server later receives this JWT, it performs the same signing calculation itself, using the matching key it already knows about or trusts, and compares its own freshly computed result against the signature that came attached to the token. If even a single character in the header or payload had been altered after the token was originally signed, the recomputed signature would come out completely different, and the mismatch would immediately reveal the tampering.
This is similar to how a shipping company might weigh a sealed package at the warehouse and print that exact weight on the shipping label. If someone secretly opens the box and adds extra items along the way, the package will weigh more than the label claims at the next checkpoint, immediately revealing that something changed, even without ever needing to open the box to check.
7Two Families of Signing Algorithms
Not every JWT is signed the same way. Understanding the two main families clarifies who can create tokens and who can only verify them.
Symmetric Signing (Shared Secret)
- The exact same secret key is used both to create the signature and to check it later.
- Simple and fast, well suited when only one trusted party, such as the Authorization Server itself, ever needs to verify tokens.
- Risky to share widely, since anyone holding the shared secret could also forge valid-looking tokens.
Asymmetric Signing (Public / Private Key Pair)
- A private key, known only to the Authorization Server, creates the signature; a matching public key, which can be shared freely, checks it.
- Many different Resource Servers can safely verify tokens using the public key, without ever being able to forge new tokens themselves.
- Slightly more computational overhead and key-management complexity than the symmetric approach.
Because OAuth 2.0 systems often involve many independent Resource Servers that all need to verify tokens issued by one central Authorization Server, asymmetric signing is a natural fit: the public key can be published openly, while only the Authorization Server retains the ability to actually create valid tokens.
8JWT Access Tokens Versus Opaque Access Tokens
Since OAuth 2.0 does not require any particular token format, it is worth comparing the two dominant styles directly.
JWT Access Tokens
- Carry readable claims directly inside the token, so a Resource Server can check permissions without an extra network call.
- Verification is fast, using only local signature checking once the correct key is known.
- Every recipient of the token can read its contents, since it is encoded, not encrypted.
- Cannot be instantly invalidated before their built-in expiration time without extra infrastructure, since Resource Servers check them locally.
Opaque Access Tokens
- Look like meaningless random strings and reveal nothing at all if intercepted.
- Require the Resource Server to call back to the Authorization Server to check validity and details on every use, adding network overhead.
- Can be revoked instantly and centrally at any moment, since every check passes back through the Authorization Server.
- Simpler to reason about for teams that are not yet comfortable managing signing keys.
Neither style is universally “better” — they represent a genuine trade-off between the speed and independence of local verification and the tighter, centrally controlled revocation that comes from always checking back with the Authorization Server. Many large-scale systems address this trade-off by combining both approaches: JWTs with short lifespans for everyday API calls, alongside a separate, centrally checked mechanism for anything that needs instant revocation.
9Security Considerations
Algorithm Confusion
A poorly written verifier might trust whatever algorithm the token itself claims to use in its header, letting an attacker switch to a weaker algorithm. Verifiers should be told explicitly which algorithm to expect.
The “none” Algorithm Trap
The JWT specification technically allows an “none” algorithm meaning no signature at all. A careless verifier that accepts this would accept completely unsigned, freely forgeable tokens.
Skipping Expiration Checks
A verifier that checks the signature but forgets to check the “exp” claim would happily keep accepting a token long after it was meant to stop working.
Sensitive Data in the Payload
Since anyone can decode a JWT’s payload, placing private information there, such as a password or a full government identification number, exposes it to anyone who ever handles the token.
A trustworthy JWT verification process must always check the signature, the expiration time, the intended audience, and the expected issuer together — checking only one of these and skipping the others leaves real gaps for an attacker to slip through.
10Best Practices and Common Mistakes
Problem
Trusting the algorithm named inside the token’s own header when deciding how to verify it.
Why It’s Harmful
This lets an attacker who modifies the token also change which algorithm the verifier uses, potentially downgrading to a weaker or nonexistent signing method.
Correct Approach
Hardcode the expected algorithm on the verifying side, and reject any token whose header claims a different algorithm than expected.
Problem
Treating a valid signature as proof that the token is safe to accept, without separately checking expiration, audience, and issuer.
Why It’s Harmful
A signature only proves the token has not been altered since it was signed — it says nothing on its own about whether the token has expired, was meant for a different service, or came from an unexpected issuer.
Correct Approach
Treat signature verification as only the first of several required checks, always followed by explicit validation of expiration, audience, and issuer claims.
Problem
Placing sensitive personal or secret information directly inside the JWT payload, assuming it is protected because it looks scrambled.
Why It’s Harmful
Because the payload is only encoded, not encrypted, anyone who obtains the token, including through browser history or logs, can decode and read it within seconds.
Correct Approach
Keep the payload limited to identifiers and permissions that are safe for any legitimate holder of the token to see, and fetch genuinely sensitive details separately, over a protected channel, when actually needed.
11Real-World Examples You Have Probably Already Used
“Sign in With” Identity Tokens
When you log into a website using an existing account from a major identity provider, the piece of information proving who you are is very often delivered as a JWT, called an ID token, carrying your basic profile claims.
API Access Tokens Between Microservices
Large systems built from many small internal services often pass JWTs between those services, letting each one independently verify a request’s permissions without repeatedly calling a central authorization service.
Single Sign-On Across Company Tools
Organizations that let employees move between many internal tools without logging in again and again frequently rely on JWTs to carry a verified identity from one tool to the next.
Short-Lived, Purpose-Specific Links
Some email confirmation links or one-time action links encode a signed JWT directly into the link itself, letting the receiving server verify the request’s authenticity and expiration without a database lookup.
12Frequently Asked Questions
Yes, assuming they have the token itself. The header and payload are only encoded, not encrypted, so anyone holding the token can decode and read both sections in seconds using a basic, freely available tool.
Technically the text can be edited by anyone, but doing so breaks the mathematical relationship between the content and the signature, so any properly implemented verifier will immediately detect the mismatch and reject the altered token.
No. OAuth 2.0 is a framework describing how permission is granted and tokens are issued. A JWT is simply one popular format those tokens can be written in — OAuth 2.0 works equally well with opaque, non-JWT tokens.
Because a JWT is verified locally using its signature, instant revocation is not built in by default. Systems that need this typically keep token lifespans very short, or maintain a separate, centrally checked list of revoked token identifiers alongside the JWT itself.
Length mostly reflects how many claims are packed into the payload and which signing algorithm was used, since some algorithms produce naturally longer signature sections than others.
13Summary and Key Takeaways
A JWT is best understood as a sealed, readable letter rather than a locked box. Its three parts — header, payload, and signature — work together to carry useful, structured information while guaranteeing that nothing has been quietly altered since it was created. The header describes how the token was signed, the payload carries the actual claims, and the signature acts as the tamper-evident seal tying the two together. Because a JWT can always be read by anyone holding it, its real security value lies entirely in integrity, not secrecy, which shapes every best practice covered in this tutorial, from choosing the right signing algorithm to keeping sensitive data out of the payload entirely.
Key Takeaways
- Three parts, joined by dots — header, payload, and signature, each with a distinct job.
- Encoded, not encrypted — anyone holding a JWT can read its header and payload contents.
- The signature proves integrity — it detects tampering, it does not hide information.
- Claims carry the useful facts — standardized fields like issuer, subject, and expiration, plus optional custom fields.
- Two signing families exist — a shared secret for simple setups, or a public/private key pair for wide, safe verification.
- Trade-off versus opaque tokens — fast, independent local verification versus instantly revocable, centrally checked tokens.
- Never put secrets in the payload — treat it as visible to anyone who ever holds the token.