A JWT (JSON Web Token, RFC 7519) is a self-contained token that carries signed claims as JSON, encoded as three Base64URL parts joined by dots: `header.payload.signature`. Because the server can trust the contents by verifying the signature alone, without a session lookup, JWTs are the de facto standard for stateless authentication.
Usually Authorization: Bearer <header>.<payload>.<signature>The header holds the signing algorithm (alg) and type; the payload holds claims. Standard claims include iss (issuer), sub (subject), aud (audience), exp (expiry), nbf (not-before), iat (issued-at), and jti (token id). The signature signs the header and payload with either a symmetric key (HS256, shared secret) or an asymmetric key (RS256/ES256, private-key sign, public-key verify). Crucially, the payload is signed, not encrypted: anyone can decode and read it, so never put passwords or personal data in it.
On verification, beyond checking the signature you must also validate exp (not expired), aud (am I the intended audience), and iss (is this a trusted issuer). Skipping these three lets expired tokens or tokens meant for another service pass straight through.
The price of statelessness is difficult revocation. As long as the signature is valid and it is before exp, the server keeps trusting the token, so forced logout or account suspension is hard to apply instantly. That is why access tokens are kept short-lived, and if needed a jti blacklist or a token-version field is stored server-side for a semi-stateful revocation strategy.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiaXNzIjoiZXhhbXBsZS5jb20iLCJhdWQiOiJhcGkiLCJleHAiOjE3MzUwMDAwMDB9.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8Ucurl -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiI...' https://api.example.com/meconst jwt = require('jsonwebtoken');
try {
const claims = jwt.verify(token, PUBLIC_KEY, {
algorithms: ['RS256'], // never allow 'none'
issuer: 'example.com',
audience: 'api'
});
} catch (e) { res.status(401).end(); }import jwt
claims = jwt.decode(
token, PUBLIC_KEY,
algorithms=['RS256'], # pin the algorithm
issuer='example.com', audience='api',
options={'require': ['exp', 'iss', 'aud']}
)