#2: Understanding JWT Claims, Headers, and Custom Payloads
In our previous post Understanding JWTs: The Complete Guide to API Authentication, we introduced JSON Web Tokens (JWTs) and their role in stateless authentication systems. Now, let's delve deeper into the components that make JWTs powerful and flexible: claims, headers, and custom payloads.
The JWT Header
The header typically consists of two parts: the type of the token, which is JWT, and the signing algorithm being used, such as HMAC SHA256 or RSA. For example:
{ "alg": "HS256", "typ": "JWT" }
This header is Base64Url encoded to form the first part of the JWT. The header provides flexibility in our design and allows for different signing algorithms to be utilized.
The JWT header is designed to be flexible, supporting a wide range of signing algorithms. This gives application developers the freedom to select the key material and algorithms that best suit their needs. It also enables systems to adapt to future security improvements without changing the JWT format itself.
Regardless of which algorithm is chosen, the core idea remains the same: the header and payload are signed to ensure the integrity and authenticity of the token.
The flexibility of JWT is also its biggest weakness. as several attacks have been found in the past that exploit this flexibility. JOSE is a kit-of-parts design, allowing develop- ers to pick and choose from a wide variety of algorithms, and not all combinations of features are secure.
We'll cover "Signing, Verifying, and Choosing the Right Algorithms" in part three of our series.
What Are JWT Claims?
JWT claims are statements about an entity (typically, the user) and additional data. These claims are encoded in the payload of a JWT and are used by the server to make authorization decisions. Claims are categorized into three types: registered, public, and private.
Registered Claims
Registered claims are a set of predefined claims that are recommended to provide a set of useful, interoperable claims. They are not mandatory but serve as a standard across different systems. Some of the most commonly used registered claims include:
| Claim | Name | Purpose | |
| ----- | --------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| iss
| Issuer | Indicates WHO created the JWT token. Often the URI of the authentication service. | |
| sub
| Subject | Identifies the subject of the JWT (the user). Usually a username or email | |
| aud
| Audience | Specifies the intended recipients of the JWT. This is typically an array of strings, but if there's only one recipient, a single string value can be used instead. The recipient must verify that its identifier is included in the audience; if not, the JWT should be rejected. Usually, the audience consists of URIs representing APIs where the token is valid. | |
| exp
| Expiration Time | The UNIX time on or after which the JWT must not be accepted The token is expired after this time. | |
| nbf
| Not Before | A UNIX time. The JWT token should be rejected if utilized before this time | |
| iat
| Issued At |The UNIX time at which the JWT was created. | |
| jti
| JWT ID | A unique ID for the JWT, which can be utilized to detect replay and for token revocation mechanisms. |
These claims indicate who is using the token, which services should accept it, who issued it, and when it is valid. The registered claims establish a baseline for authenticating access to our API.
Public and Private Claims
-
Public Claims: These can be defined at will by those using JWTs. To avoid collisions, they should be defined in the IANA JSON Web Token Registry or be defined as a URI that contains a collision-resistant namespace. Public claims are useful when wanting to standardize information sharing between public platforms and are outside the scope of this series.
-
Private Claims: These are custom claims created to share information between parties that agree on using them and are neither registered nor public claims. They are used to convey information specific to the application, such as user roles or permissions.
Custom Claims and Real-World Use Case
Depending on the use case of your API, you can add custom claims to your tokens to represent information more specific to your application. For instance, you might include claims like role
, permissions
, or tenant_id
to manage user access and segmentation.
Use Case: Implementing Role-Based Access Control (RBAC)
Imagine you have a multi-tenant project management platform where users can have different roles such as "Admin", "Project Manager", or "Developer". You can include a custom claim in the JWT to represent the user's role:
{ "sub": "1234567890", "name": "Jane Doe", "role": "Project Manager", "iat": 1516239022 }
By including the role
claim, your application can make authorization decisions based on the user's role without additional database queries.
Conclusion
Understanding JWT claims and headers is crucial for implementing secure and efficient authentication and authorization in your applications. By leveraging registered claims and thoughtfully designing custom claims, you can create a robust security model that suits your application's specific needs.(Stytch)
Stay tuned for the next installment in our series, where we'll explore best practices for securing JWTs and managing their lifecycle.