A JWT has the form header.payload.signature, where the first two parts are Base64URL-encoded JSON and the last part proves the token was signed. Common claims such as sub, iss, aud, exp, and iat describe who the token is about, who issued it, who should accept it, when it expires, and when it was created. A server verifies a JWT by checking the signature, algorithm, expiration time, issuer, audience, and required claims.
JWTs should not store secrets because they are encoded, not encrypted, unless a separate encryption format is used.
Key Facts
- A JWT has three parts separated by periods: header.payload.signature.
- The header usually contains JSON such as {"alg":"HS256","typ":"JWT"}, where alg names the signing algorithm.
- The payload contains claims such as sub for subject, iss for issuer, aud for audience, exp for expiration time, and iat for issued-at time.
- The signature is created from Base64URL(header) + "." + Base64URL(payload) and a secret or private key.
- For HMAC-based JWTs, the simplified signing rule is signature = HMACSHA256(Base64URL(header) + "." + Base64URL(payload), secret).
- The exp claim is a Unix timestamp, and a token is expired when current_time >= exp.
- Base64URL encoding makes JWT parts safe for URLs by using - and _ instead of + and / and usually omitting padding =.
- A JWT is encoded and signed, but it is not private by default, so sensitive data should not be placed in the payload.
Vocabulary
- JWT
- A JSON Web Token is a compact signed token used to transmit claims between two parties.
- Claim
- A claim is a name-value statement in the payload, such as a user ID, role, issuer, or expiration time.
- Header
- The header is the first JWT section and describes metadata such as the token type and signing algorithm.
- Payload
- The payload is the second JWT section and contains the claims the receiver may use after validation.
- Signature
- The signature is the third JWT section and lets the receiver check that the token was not changed after signing.
- Base64URL
- Base64URL is an encoding format that represents data using URL-safe characters, but it does not provide secrecy.
Common Mistakes to Avoid
- Treating Base64URL as encryption is wrong because anyone who has the token can decode the header and payload.
- Skipping signature verification is wrong because an attacker could edit claims such as role or sub and create a fake token.
- Accepting any alg value from the token is wrong because the server must restrict allowed algorithms to trusted choices.
- Ignoring exp, iss, or aud is wrong because a token may be expired, issued by the wrong system, or meant for a different application.
- Storing long-lived JWTs in unsafe browser storage is wrong because stolen tokens can be reused until they expire or are revoked.
Practice Questions
- 1 A JWT string is abc.def.ghi. Which part is the payload, and which part is the signature?
- 2 A token has exp = 1710003600 and the current Unix time is 1710003590. Is the token expired?
- 3 A JWT payload contains {"sub":"42","role":"admin","exp":1893456000}. Name two claims and explain what information they provide.
- 4 Why should a server verify both the signature and the audience claim before trusting a JWT from a client?