“Missing state cookie from login request (check login URL, callback URL and cookie config)” Error

Overview

A custom invitation flow was implemented in the Next.js app by creating a custom login route that accepts invitation and organization parameters. The authorize URL constructed by the custom login route is similar to

  • https://{customer domain}/authorize?client_id=${process.env.NEXT_PUBLIC_AUTH0_CLIENT_ID}&invitation=${invitation}&organization=${organization}&redirect_uri={callback url}&response_type=code

The accept invitation flow and registration flow work. However, after successfully authorizing the account, it redirects to the callback page with a URL (https://{callback_url}?code=) and throws the below error:

[CallbackHandlerError]: Callback handler failed. CAUSE: Missing state cookie from login request (check login URL, callback URL and cookie config).

From the above reconstructed /authorize URL, the state param was not set with a value.

In the HAR file, the login call is:

Nextjs-auth0 3.5.0 version was used, and the Next.js app was deployed to an EC2 instance on AWS.

This article addresses the following questions:

  • Should the value for the state param be set explicitly to avoid the issue when implementing the custom login flow for inviting users to an organization?
  • What is the best practice for implementing the “Organization Invitation” flow?

Applies To

  • /authorize URL
  • Next.js app
  • Callback page

Cause

If SDK’s login handler is used, the login request would look like https://{domain}/api/auth/login. Please check out this document.

Login via the SDK handler is essential ( /api/auth/login) as it sets the state cookie, which is subsequently used in the callback /api/auth/callback api call. This leads to the failure of the callback API call as the state cookie is missing.

The /api/auth/login api call that we expect to be called to set cookies has to be of type document instead of fetch.

Is needed to visit /api/auth/login in the address bar to set the cookies, then be redirected back to /api/auth/callback to read them.

Solution

The state param is a must in /authorize URL to successfully authorize the user.
Directly calling the /authorize endpoint with manually added params is not a recommended approach, as it is prone to mistakes and misconfiguration.

The ideal approach is to follow the steps mentioned in the SDK and use its configuration to achieve a customized organization invitation flow.

  1. NextJs SDK supports the configuration of Organisation invitation flow.

  2. Users can make use of Module handlers/login > Interface AuthorizationParams.

    • With the help of the above interface, it is possible to configure organization & invitation properties in the SDK.

      Sample snippet

      import { handleAuth, handleLogin } from '@auth0/nextjs-auth0';
      
      export const GET = handleAuth({
        login: async (req, res) => {
          try {
            return await handleLogin(req, res, {
              authorizationParams: { organization: '<org_id>', invitation: '<invitation>'}
            });
          } catch (error) {
            console.error(error);      
          }
        }
      });
      
  3. Subsequently, when they happen to hit the /api/auth/login URL, the SDK will make the required /authorize with all required props.