Exploring OIDC grants: understanding and troubleshooting the "invalid_grant" error

Learn the essentials of OpenID Connect (OIDC) grants, and how to troubleshoot the "invalid_grant" error.
Charles
CharlesDeveloper
September 19, 20237 min read
Exploring OIDC grants: understanding and troubleshooting the "invalid_grant" error

Background

In our community, we often hear a recurring question from our users: What's the deal with the "invalid_grant" error in Logto? Like #503

It's a common challenge and a blocker for some of our users when integrating Logto into their own applications. However, the reasons behind this error vary from case to case, and sometimes it is hard to explain with limited context provided. Therefore, understanding the exact OIDC concept and learning the way to troubleshoot the issue is essential for everyone.

Now let's delve into the basics of OIDC grants.

OIDC grants explained

As we have introduced in a blog post earlier, OpenID Connect (OIDC) is a protocol built on top of OAuth 2.0.

In the context of OIDC or OAuth2, a grant is a set of permissions granted by the resource owner (usually the user) to a client application. Grants are essential for the client application to access the user's identity information and other protected resources. OIDC defines several grant types, each suited for a different scenario and the way an application gets an access token.

Here's an analogy to help you better understand OIDC grants.

Imagine you're traveling to different countries, and each country demands a visa stamp for entry. In this scenario, your passport serves as your user account, containing your personal information. OIDC grants are like the ways you apply for a visa to enter a country. When a visa is issued to you, you essentially obtain the "token" to enter that country.

Similarly, when using an application, the grant request is the action you request the authorization server to grant you access. The authorization server validates your identity, and issues you the "visa" (access token) to sign in to the application.

Commonly used OIDC grant types:

  1. Authorization Code Grant: This is the most commonly used grant type in OIDC. It involves redirecting the user to an authorization server, obtaining an authorization code, redirecting back to the application and exchanging the code for an access token. Think of it as the standard process of applying for a visa from the embassy before entering a foreign country.
  2. Refresh Token Grant: In OIDC, this grant type allows a client application to obtain a new access token using a refresh token that was previously issued. It's commonly used to extend a user's session without requiring them to re-enter their credentials. Imagine your visa comes with a magic card that allows you to extend your stay in the foreign country without going through the customs again.
  3. Implicit Grant: This grant type is used for legacy browser-based applications and is less secure than the Authorization Code Grant. It returns the access token directly to the client application. It works like a "visa on arrival", as no prior visa application is required.
  4. Client Credentials Grant: Suitable for server-to-server communication, this grant type allows a client application to authenticate directly with the authorization server using its credentials (client ID and client secret). It's akin to a special agent showing a special job badge to enter the country without going through the visa application process.

Grant object model:

In Logto, grant is persisted in database as an object entity, containing information such as user account ID, application ID, associated OIDC resources and scopes, expiration time, and more. Each refresh token and access token is associated with a specific grant object.

Grant requests:

HTTP requests made to the authorization server through APIs. A client application can send grant requests to OIDC token endpoint for various purposes, including applying for a new grant (e.g., signing in and obtaining refresh and access tokens), updating grant details (e.g., exchanging a refresh token for a new access token), or revoking a grant (e.g., revoking all tokens issued to logged-in users and terminating their access).

A typical authorization code grant request looks as follows:

Request URL: "https://tenant-id.logto.app/oidc/token"
Request Method: "POST"
## Request payload
client_id: "<your-client-app-id>"
code: "<a-random-string-generated-by-auth-server>"
code_verifier: "<a-random-string-generated-by-client>"
redirect_uri: "https://your-domain.com/callback"
grant_type: "authorization_code"

Understanding the "invalid_grant" error

Encountering an invalid_grant error in OIDC typically indicates that the grant type or the data associated with the grant request is invalid or not supported. Here are some common reasons behind this error:

  1. Incorrect grant type: Using the wrong grant type for your application can result in an invalid_grant error. Ensure that you're using the appropriate grant type by leveraging Logto SDKs.
  2. Mismatched redirect URIs: When exchanging an authorization code for tokens, the redirect URI used in the request must match the one used during the initial authorization request. A mismatch can result in an invalid_grant error.
  3. Expired or consumed authorization code: In the Authorization Code sign-in flow, the authorization code has a limited lifespan, and will be marked as "consumed" once used to acquire tokens. Attempting to exchange an expired or consumed code for an access token will result in an invalid_grant error.
  4. Expired or rotated refresh token: When exchanging a refresh token for an access token, the invalid_grant error occurs if the refresh token is already expired. Moreover, for enhanced security, Logto enables refresh token rotation by default. Requesting the token endpoint with the same refresh token a second time is considered using a "rotated" refresh token and will be rejected.
  5. Missing mandatory data or request headers: When composing a grant request, the mandatory parameters and request headers must be provided for the given grant type. For example, the client ID must be provided in all grant requests, and client ID and client secret must be provided for Client Credentials Grant. This risk can also be mitigated by leveraging Logto SDKs.
  6. Other reasons: This error can also occur due to reasons like client credential mismatch, grant expired or not found, refresh token not found, etc.

Troubleshooting

Some tips to troubleshoot the "invalid_grant" error effectively:

  1. Always use a Logto client SDK to integrate Logto into your application, in order to make sure the grant requests is being made to the respective endpoint and with correct data.
  2. Verify that your app credentials and redirect URIs match the configurations in the Admin Console.
  3. Avoid making redundant requests, especially for SPAs like React and Vue, where page components can re-render due to dependency changes. Ensure that functions used to exchange codes or refresh tokens for access tokens are not triggered multiple times with the same request parameters. This is a common mistake made by some of our users. Typically if you can see multiple "token" requests in your debug console, the first one is successful but the subsequent ones are all failed, check their request parameters to see if they are using the same "code" or "refresh token". Remember, you can only use a code and refresh token ONCE in grant requests.
  4. Check expiration times. For example, if your refresh token is expired (by default 14 days) and you receive the invalid_grant error, you should properly handle it by initializing a user sign-in flow again. If you are using Logto SDK, you can call signIn() function again to redirect your users back to sign-in page.
  5. Monitor audit logs. Go to Admin Console → Audit Logs, find the error log associated with the incident and check the detailed error stack trace. Usually, there's a more specific reason in the stack trace behind the invalid_grant error, such as "Grant not found" or "Refresh token expired".

Closing notes

The invalid_grant error can be challenging and confusing for beginners, but with a clear understanding of OIDC grants and attention to detail, you can identify and tackle down the issue yourself. Join our discussions on Discord or GitHub, and let us know if this blog has helped clarify the confusion and identify the issues you are facing. The Logto dev team is always happy to assist you.

Together, let's build a seamless and secure authentication experience for your beloved applications.