CodePark/ questions / JWT in depth
START PRACTICINGPRACTICE
Backend question · Auth & security › JWT in depth

Describe the structure of a JWT and list everything a server must validate before trusting one.

header:  { "alg": "RS256", "typ": "JWT", "kid": "2024-key-1" }
payload: { "iss": "https://auth.example.com", "sub": "42",
           "aud": "orders-api", "exp": 1767225600, "iat": 1767222000 }

token = base64url(header) + "." + base64url(payload) + "." + base64url(signature)

A JWT is three base64url parts joined by dots: header.payload.signature.

  • The header names the algorithm. It often also has a key id (kid).
  • The payload holds the claims (the data about the user and the token).
  • The signature is computed over the first two parts.

In the common JWS form, the token is signed, not encrypted.

Before trusting it, the server must check these things:

  • Verify the signature with the expected key.
  • Only accept algorithms on its own allowlist. Reject none, and reject any algorithm that doesn't match the key type.
  • Check exp (expiry time) and nbf ("not before" time). Allow a small clock skew, because server clocks differ a little.
  • Check that iss (issuer) is the issuer it trusts.
  • Check that aud (audience) contains this API. Then a token made for another service is refused.

After that come application checks, such as the token type and scopes (what the token is allowed to do). Only after all these checks should the server use the claims for authorization.

  • A JWT is header.payload.signature in base64url, and it is signed, not encrypted.
  • Verify the signature with the right key.
  • Pin the allowed algorithms and reject none.
  • Check the exp, nbf, iss and aud claims.
  • Then check the scopes or token type.