A JSON Web Token, or JWT, is a compact format for carrying claims between systems. It is defined by RFC 7519 and is commonly used in authentication and authorization flows.
A JWT is only a token format. It does not authenticate a user or decide permissions by itself. An application decides when to issue a token, which claims to include and what those claims allow.
The three parts
A common signed JWT contains three Base64url-encoded parts separated by dots:
header.payload.signature
Header
The header identifies the token type and signing algorithm.
{ "alg": "HS256", "typ": "JWT"}
Payload
The payload contains claims about the subject and the token itself.
{ "sub": "1234567890", "role": "admin", "iss": "https://auth.example.com", "aud": "example-api", "exp": 1536192000}
Common registered claims include the subject (sub), issuer (iss), audience (aud) and expiration time (exp). Applications may also add their own claims, such as a role.
Base64url is an encoding, not encryption. Anyone holding the token can decode its header and payload, so they should not contain passwords, secrets or other sensitive data.
Signature
For an HMAC-signed token, the signature is created from the encoded header and payload using a shared secret:
signingInput = base64url(header) + "." + base64url(payload)signature = HMACSHA256(signingInput, secret)token = signingInput + "." + base64url(signature)
The signature protects the token from unnoticed modification. If someone changes the payload without the signing key, the calculated signature will no longer match.
HMAC algorithms use the same secret to sign and verify. Asymmetric algorithms such as RSA use a private key to sign and a public key to verify.
A typical request flow
- A server authenticates the client using credentials or another login method.
- The server creates and signs a JWT, then returns it to the client.
- The client sends the token with later requests, commonly as
Authorization: Bearer <token>. - The receiving service verifies the token before trusting any claim inside it.
What verification must check
A backend should do more than decode the token. It must:
- Allow only the expected signing algorithms.
- Verify the signature with a trusted secret or public key.
- Reject an expired token and respect its not-before time when present.
- Confirm the expected issuer and audience.
- Use the claims only after all checks succeed.
A valid signature proves that the signed content has not changed and came from an entity holding the signing key. It does not encrypt the content or prevent a stolen token from being reused before it expires.
JWT, OAuth and OpenID Connect
These terms are related but not interchangeable:
- JWT defines a token format.
- OAuth 2.0 defines a framework for delegated authorization. Its access tokens may be JWTs, but they do not have to be.
- OpenID Connect adds authentication to OAuth 2.0 and represents its ID Token as a JWT.
What I want to remember
A signed JWT is a portable set of claims with an integrity check. The payload is readable, the signature makes tampering detectable and the backend must validate the signature and claims before trusting it.