What are JWT tokens?
What they are, how they work, and why your app needs them
You log into an application. A few seconds later, you are in — and the app knows who you are, what you are allowed to do, and keeps knowing it for the rest of your session. But how? The server did not ask you to log in again on the next page. It did not look you up in a database on every click. Something is carrying your identity around, and in most modern applications, that something is a JWT token.
This article explains what JWT tokens are, what they contain, and why they have become the standard mechanism for authentication in modern applications.
The problem JWT tokens solve
Before tokens, the most common approach was server-side sessions. When you logged in, the server created a session record in memory or in a database, assigned it an ID, and sent that ID to your browser as a cookie. On every subsequent request, the browser sent the cookie back, the server looked up the session, found your user data, and proceeded.
This works — but it has limitations. The server has to store and look up session data on every single request. If you have multiple servers behind a load balancer, they all need access to the same session store. If you are building a mobile app or a third-party API integration, cookies are awkward to work with. As applications became more distributed, sessions became a bottleneck.
The idea behind JWT tokens is different: instead of storing your identity on the server and handing you a key to retrieve it, the server gives you the identity data directly — packaged in a way that cannot be tampered with.
What is a JWT
JWT stands for JSON Web Token. It is a compact, self-contained string that carries information about a user — or about the permissions granted to an application — in a format that any system can read and verify independently.
A JWT looks like this:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTYiLCJuYW1lIjoiSmFuZSBEb2UiLCJlbWFpbCI6ImphbmVAZXhhbXBsZS5jb20iLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MTcwMDAwMDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
It is not encrypted by default — it is just encoded. Which means you can decode it and read what is inside. The three parts separated by dots are the header, the payload, and the signature.
What a JWT actually contains
The header describes the token itself — specifically, which algorithm was used to sign it. This tells the receiver how to verify the signature.
The payload is where the actual information lives. It is a JSON object containing a set of claims — statements about the user or the context of the token. A typical payload looks like this:
{
"sub": "123456",
"name": "Jane Doe",
"email": "jane@example.com",
"role": "admin",
"exp": 1717000000
}
Each field is a claim. Some are standardized — sub is the subject (the user identifier),
exp is the expiration timestamp. Others like role are custom claims
that your application defines based on its own needs.
The signature is what makes the token trustworthy. It is generated by the authorization server using a private key, and it covers both the header and the payload. If anyone modifies even a single character of the token, the signature becomes invalid.
💡 Encoded, not encrypted
The payload of a standard JWT is Base64-encoded, which means anyone who has the token can read its contents. Never put sensitive information — passwords, credit card numbers, personal data — inside a JWT payload. The signature guarantees integrity, not confidentiality.
How the signature makes it trustworthy
When your authorization server issues a JWT, it signs it with a private key that only the server holds. When an API receives that token, it verifies the signature using the corresponding public key — which it can obtain from the authorization server's discovery endpoint.
If the signature is valid, the API knows two things: the token was genuinely issued by the authorization server, and its contents have not been modified since. No database lookup required — the token is self-contained and self-verifiable.
This is why JWT tokens work so well in distributed systems. Any service that has the public key can independently verify any token, without coordinating with a central session store.
Why your app needs this
JWT tokens solve several practical problems at once:
- Stateless authentication — the server does not need to store session data. Every request is independently verifiable.
- Scalability — any instance of your API can validate any token, with no shared state between servers.
- Cross-domain access — tokens travel in HTTP headers, making them easy to use across different domains and services.
- Rich context — a single token can carry roles, permissions, and user data, reducing the need for additional lookups.
- Standard interoperability — JWT is an open standard. Any framework, in any language, knows how to handle them.
The flip side
JWT tokens are not without trade-offs, and understanding them is important before relying on them in production.
The most significant limitation is revocation. Because a JWT is self-contained and
stateless, there is no built-in way to invalidate it before it expires. If a token is stolen, or a
user's permissions change, the token remains valid until its exp timestamp is reached.
This makes token lifetime a critical security parameter — access tokens should be short-lived,
typically between 5 and 15 minutes.
There are approaches to handle revocation — reference tokens, token introspection, blocklists — but they all introduce some degree of server-side state, partially trading away the stateless advantage. The right choice depends on your application's security requirements.
⚠️ Short lifetimes are not optional
A JWT that is valid for 24 hours is a significant security risk. If it is intercepted, an attacker has a full day to use it. Keep access token lifetimes short, and use refresh tokens to maintain sessions without compromising security.
Managing JWT tokens without the complexity
Handling JWT tokens correctly — signing certificates, token lifetimes, revocation strategies, claims configuration — requires careful decisions at every step. IdentitySuite is built on OpenIddict and handles all of this out of the box, with secure defaults and a full admin UI to manage every aspect of your token configuration without writing a line of code.
About IdentitySuite
IdentitySuite simplifies enterprise authentication for .NET developers. Built on proven technologies like ASP.NET Core Identity and Openiddict, we eliminate the complexity of OAuth 2.0 and OpenID Connect implementation while maintaining enterprise-grade security standards.