A JWT is composed of three parts, separated by a period (.):
<header>.<payload>.<signature>
- Header: a JSON object that contains information about the token, such as its type and the algorithm used to produce the signature, for example, { "alg": "HS512", "typ": "JWT" }.
- Payload: A JSON object contains a set of claims, such as its identity and permissions, for example, { "sub": "e@ma.il" }.
- Signature: A string that is either a Message Authentication Code (MAC) or digital signature. The purpose of the signature is to ensure the authenticity and integrity of the payload.
The header and payload are then base-64 encoded to ensure they are compact. A simple JWT may look like this (new lines have been inserted for readability):
eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiJlQG1hLmlsIn0
.
m5ZdZVXkUvur6kYndOAtp3nFdhGSqiK5S13s53y0N5EJukYE1pWdaSOY_a3lZEOsDSJ5xsUw5ACxG8VyCWUleQ
When the header and payload are base-64 decrypted, their information is once again revealed:
{ "alg": "HS512", "typ": "JWT" } # Header
{ "sub": "e@ma.il" } # Payload
Because JWTs are base-64 encoded, they are URL-safe. This means a JWT can be supplied through the URL, in the body of an HTTP request, or as a value inside an HTTP Authorization header.
Now, let's examine each part of the JWT in more details, starting with the header.