If you have ever inspected a login request in your browser’s network tab, you have probably seen a long string of gibberish with two dots in it, sitting in an Authorization header. That string is almost certainly a JWT, short for JSON Web Token. It is one of the most common ways modern web apps and APIs answer a single question on every request: who is this, and can I trust that they are who they claim to be?
The idea is simple once you see inside. A JWT packs a few facts about a user into a small JSON object, then attaches a cryptographic signature so the server can confirm those facts have not been changed. The token travels with each request, the server checks the signature, and that is the whole handshake. No database lookup needed to know who is calling.
The three parts of a JWT
A JWT is three chunks of text joined by dots, in the shape header.payload.signature. Each of the first two parts is a JSON object that has been Base64URL-encoded, which is a URL-safe cousin of ordinary Base64 encoding. That encoding is why the token looks like noise, but it is worth being clear: encoding is not encryption. Anyone can decode those parts and read them.
The header
The first part is a small JSON object that describes the token itself. It names the type (JWT) and the signing algorithm used, for example HS256 or RS256. The server reads this to know how to check the signature. That is mostly all it does.
The payload
The middle part carries the actual content, a set of claims. A claim is just a fact, stored as a key and value. Some are standardised, like sub (the subject, usually a user ID), iat (issued-at time) and exp (expiry time). Others are custom, like a role or an email. Because the payload is only encoded, never put a password or anything truly secret in here. Treat it as readable by anyone who gets the token.
The signature
The last part is the clever bit. The server takes the encoded header and payload, runs them through the signing algorithm together with a secret key, and produces the signature. When the token comes back on a later request, the server repeats the calculation and compares. If even one character of the payload was altered, the signatures will not match and the token is rejected. The signature does not hide the data, it guarantees the data is unchanged and came from someone holding the key.
How the signature actually works
There are two common families of algorithm, and the difference matters. With a symmetric algorithm like HS256, one shared secret both creates and verifies the signature. It is simple, but every party that needs to verify the token also needs the secret, which can verify and forge tokens too.
With an asymmetric algorithm like RS256, there are two keys: a private key that only the issuer holds and uses to sign, and a public key that anyone can use to verify. This is public-key cryptography, the same asymmetric approach that TLS certificates use, and it scales far better, because you can hand the public key to any number of services without letting them mint tokens of their own.
What a JWT is and is not good for
JWTs shine for stateless authentication. Because the token carries its own proof, a server can trust a request without looking anything up. That makes them a natural fit for APIs, single sign-on, and microservices that need to pass identity around. Each service just needs the key to verify.
The flip side is what they are bad at. A JWT is hard to revoke before it expires, because the whole point is that the server does not keep state about it. If a token is stolen, it stays valid until the exp time passes, so short lifetimes and a separate refresh mechanism matter. And, to repeat the point people miss most often: a standard JWT is signed, not encrypted, so it protects integrity, not secrecy.
Decoding a JWT safely
To read a token, you split it at the two dots and Base64URL-decode the first two parts. You do not need the secret for this, because, again, the contents are not encrypted. That is exactly why you should never paste a real, live token into a random website you do not trust: the payload may hold a session that someone could replay. A decoder that runs locally in your browser, like our free JWT decoder, is the safe way to inspect one, because nothing you paste ever leaves your machine.
This is a recurring theme across the developer formats you handle every day. A UUID looks random but is just an identifier, Base64 looks encrypted but is just transport, and a JWT looks locked but is just signed. Knowing which is which saves you from a whole category of mistakes. If you spend a lot of time moving these strings around a shell, our guide to copy and paste in the terminal covers the shortcuts that do not cancel your command.
A quick example walkthrough
Say a user logs in. The server builds a payload like { "sub": "1234", "role": "admin", "exp": ... }, encodes it with the header, signs the pair with its key, and sends back the finished token. The browser stores it and attaches it to the next request. The server verifies the signature, sees the user is admin and the token has not expired, and serves the response. No session table, no lookup. That self-contained quality is the entire appeal, and also the reason expiry and key hygiene are the things you actually have to get right.
Frequently asked questions
Is a JWT encrypted?
Not by default. A standard signed JWT (a JWS) is only encoded, not encrypted, so anyone holding the token can read the payload by decoding the middle section. The signature stops the contents being changed, but it does not hide them. There is a separate, less common format called JWE that does encrypt the payload, but most tokens you meet are signed and readable.
What does JWT stand for?
JWT stands for JSON Web Token. It is a compact, URL-safe way to represent a set of claims, which are just facts about a user or request, as a signed JSON object. The name is usually pronounced “jot.” It is an open standard defined in RFC 7519.
Can a JWT be faked or tampered with?
Not without the secret or private key used to sign it. If you change even one character of the payload, the signature no longer matches and a correct server rejects the token. The real risks are weak or leaked signing keys, and servers that fail to verify the signature properly, rather than the format itself being breakable.