What is an ID token, and how is it structured and encoded?
A JSON Web Token (JWT) with identity data and information about the authentication process; it consists of header, payload and signature, each base64url-encoded and joined with dots: header.payload.signature.
* Three base64url parts joined by dots; the signature covers the first two, so changing any claim breaks it. *
- Header: information about the signature and encryption, for example
{"alg": "RS256", "kid": "1e9gdk7"}, which tells the receiver which algorithm and which key to verify with. - Payload: the claims about the user and the authentication (issuer, subject, audience, timestamps...).
- Signature: computed by the issuer over
base64url(header) + "." + base64url(payload), with a keyed MAC (HS256) or a private key (RS256, ES256).
Encoding: jwt = base64UrlEncode(header) + "." + base64UrlEncode(payload) + "." + base64UrlEncode(signature). Base64url is base64 with - and _ instead of + and / and no padding, so the token can travel safely in URLs and headers. Every JSON header starts with {", which base64url-encodes to eyJ, so JWTs are easy to recognise.
To protect it against modification it is signed (a JWS); it can additionally be encrypted (a JWE) if the claims must stay confidential.
Go deeper:
jwt.io debugger — paste a token to see header and payload decoded and test the signature.
jwt.io: Introduction to JSON Web Tokens — structure, signing and typical uses, with diagrams.
JSON Web Token (Wikipedia) — structure, standard fields and known vulnerabilities.