Add custom claims for JWT access tokens with Logto to boost your authorization
In this article, we will introduce how to use Logto custom JWT claims feature to improve the flexibility of authorization and the performance of the service provider through a real-world example.
In previous articles, we mentioned that more and more systems are using JWT-format access tokens for user authentication and access control. One of the important reasons for this is that JWT can contain some useful information, such as user roles and permissions. This information can help us pass user identity information between the server and client, thereby achieving user authentication and access control.
Usually, the information contained in JWT is determined by the authentication server. According to the OAuth 2.0 protocol, JWT usually contains fields such as sub
(subject), aud
(audience), and exp
(expiration time), which are commonly referred to as claims. These claims can help verify the validity of the access token.
However, there are countless scenarios where JWT is used for verification, and common JWT claims may often not meet user needs. People often think that since JWT can contain some information, can we add some information to it to make authorization easier?
The answer is YES, we can add custom claims to JWT, such as the current user's scope and subscription level. In this way, we can pass user identity information between the client and the server (here refers to the server that provides various different services, also called service provider), to achieve user authentication and access control.
For standard JWT claims, please refer to RFC7519. Logto, as an identity solution that supports both authentication and authorization, has extended the resource and scope claims on this basis to support standard RBAC. Although Logto's RBAC implementation is standard, it is not simple and flexible enough to fit all use cases.
Based on this, Logto launched a new feature of customizing JWT claims, which allows users to customize additional JWT claims, so that user authentication and access control can be implemented more flexibly.
How does Logto custom JWT claims work?
You can come to the Custom JWT listing page by clicking on the "JWT claims" button on the sidebar.
Let's start from adding custom claims for end-users.
In the editor on the left, you can customize your getCustomJwtClaims
function. This method has three input parameters: token
, data
, and envVariables
.
token
is the raw access token payload obtained based on the current end-user's credentials and your system configuration, and the user's access-related information in Logtodata
is all the information about the user in Logto, including all the user's roles, social sign-in identities, SSO identities, organization memberships, etc.envVariables
are the environment variables you configured in Logto for the current end-user access token usage scenario, such as API key(s) of the required external APIs, etc.
The cards on the right can be expanded to show the introduction of the corresponding parameters, and you also can set the environment variables for the current scenario here.
After reading the introductions of all the cards on the right, you can switch to the test mode, where you can edit test data and use the edited test data to check whether the behavior of the script you wrote in the code editor on the left meets your expectations.
This is a sequence diagram showing the execution process of the getCustomJwtClaims
function when an end user initiates an authentication request to Logto and eventually obtains the JWT-format access token returned by Logto.
If the Custom JWT feature is not enabled, step 3 in the figure will be skipped and step 4 will be executed right after step 2 ends. At this time, Logto will assume the return value of getCustomJwtClaims
to be an empty object, and then continue to go through subsequent steps.
Boost your authorization with custom JWT claims: a practical example
In the previous section, we introduced the working principle of the Logto custom JWT. In this part, we will show you how to use Logto custom JWT claims to improve the flexibility of authorization and the performance of the service provider through a real-world example.
Scenario setup
John's team developed an AI Assistant App that allows users to converse with AI robots to obtain various services.
The AI robot services are divided into free and paid services. Free services include special airfare recommendations, while paid services include stock predictions.
The AI Assistant App uses Logto to manage all users, which are divided into three types: free users, pre-paid users, and premium users. Free users can only use free services, pre-paid users can use all services (charged by usage), and premium users can use all services (but have rate limits to prevent malicious use).
In addition, the AI Assistant App uses Stripe to manage user payments and has its own log service to record user operation logs.
Logto configurations
We first create API resources for the AI Assistant App service and create two scopes, recommend:flight
and predict:stock
.
Then we create two roles
, free-user
and paid-user
, and assign the corresponding scopes:
- Assign the
recommend:flight
scope to thefree-user
role. - Assign both
recommend:flight
andpredict:stock
scopes to thepaid-user
role.
Finally, we create three users, free-user
, prepaid-user
, and premium-user
, and assign the corresponding roles:
- Assign the
free-user
role to userfree-user
. - Assign the
paid-user
role to usersprepaid-user
andpremium-user
.
As shown in the following figure, in order to implement the authorization information required for the scenario described above, we hope to include the roles
, balance
and numOfCallsToday
information of the currently logged-in user in the JWT. When verifying the access token in the AI Assistant App, these information can be used to quickly perform permission verification.
After configuring the envVariables
, we implement the getCustomJwtClaims
function and click the "Run test" button to see the result of the extra JWT claims based on the current test data.
Since we have not configured the test data for data.user.roles
, the roles
shown in the result is an empty array.
Check whether the custom JWT feature kicks in
According to the Logto configuration above, we got the corresponding results in the test. Next, we will use the sample app provided by Logto to verify whether our custom JWT is effective. Find the SDK you are familiar with at Logto SDKs and deploy a sample app according to the documentation and the corresponding GitHub repo.
Based on the configuration we described above, taking the React SDK as an example, we need to update the corresponding configuration in LogtoConfig:
After signing in user free_user
to the sample app that simulates the AI Assistant App, we can see the roles
, balance
, numOfCallsToday
, isPaidUser
and isPremiumUser
information we added by viewing the payload part of the JWT access token.
The values of balance
, numOfCallsToday
, isPaidUser
and isPremiumUser
are consistent with previous test, and roles
equals ["free-user"]
. This is because in the actual end-user login process, we will obtain all the accessible data of the user and process it accordingly.
For premium users, we can see that roles
is ["paid-user"]
and both isPaidUser
and isPremiumUser
are true
.
Update service provider authorization logic
In the previous steps, we added custom claims based on business needs to the user access token. Next, we can use these claims to quickly perform authorization verification.
Here we provide the logic of Logto verifying JWT access tokens on the API side. The complete code implementation can be found in the GitHub repo:
You can refer to the logic of Logto API for verifying access tokens and customize it according to your own business logic. For example, for the AI Assistant App scenario described here, you can add verification logic for custom claims such as roles
, balance
, numOfCallsToday
, isPaidUser
and isPremiumUser
in the verifyBearerTokenFromRequest
function.
The above example is for the scenario where it affects the end-user login and obtaining the JWT access token. If your use case is machine-to-machine (M2M), you can also configure custom JWT claims for M2M apps separately.
Configuring custom JWT for users will not affect the result of M2M apps obtaining access tokens, and vice versa.
Due to the generality of M2M connections, Logto does not currently provide the function of the getCustomJwtClaims
method of M2M apps to accept internal data from Logto. In other aspects, the configuration method of custom JWT for M2M apps is the same as that of user apps. This article will not elaborate on it. You can use Logto's custom JWT function to get started.
Why use custom JWT claims?
We have provided the AI Assistant App scenario for John and how to use Logto's Custom JWT feature to achieve more flexible authorization verification. In this process, we can see the advantages of the Custom JWT feature:
- Without the Custom JWT feature, users need to request an external API (such as what you do in
getCustomJwtClaims
) every time they check permissions. For the service provider that provides this API, this may increase the extra burden. With the Custom JWT feature, these information can be put directly into the JWT, reducing the frequent calls to the external API. - For service providers, the Custom JWT feature can help them verify user permissions faster, especially when the client calls the service provider frequently, improving service performance.
- The Custom JWT feature can help you quickly implement additional authorization information required by the business, and the information can be passed between the client and the service provider in a secure manner since JWT is self-contained and could be envrypted so that it is hard to be forged.
At the same time, since getCustomJwtClaims
is executed every time a user needs Logto to issue an access token, it is necessary to avoid executing overly complex logic and external API requests with high bandwidth requirements. Otherwise, it may take too long for end-users to wait for the result of getCustomJwtClaims
during the sign-in process. If your getCustomJwtClaims
returns an empty object, we strongly recommend that you temporarily delete this configuration item until you actually need to use it.
Conclusion
In this article, Logto has extended the basic JWT access token and extended the function of extra JWT claims to allow users to put additional end-user information into the JWT access token according to their business needs, so that after the user logs in, the user's permissions can be quickly verified.
We provide the scenario of John's AI Assistant App and demonstrate how to use Logto's Custom JWT feature to achieve more flexible authorization verification. We also point out some key points of using custom JWT. In combination with actual business scenarios, users can put various user-related information into the JWT access token according to their business needs, so that the service provider can quickly verify the user's permissions.