Refresh token request failed because of mfa_required

Hello, I am using Next js and auth0.
I am build a mfa system, so the users will be able to choose what MFA they want to use in the profile settings within the app I am building.
This is the setup I’ve made to allow them to do so:

  const { accessToken } = await getAccessToken();
  const enrollSMS2FA = async (phoneNumber: string) => {
    "use server";
    const response = await fetch(
      `${process.env.AUTH0_ISSUER_BASE_URL}/mfa/associate`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
        body: JSON.stringify({
          authenticator_types: ["oob"],
          oob_channels: ["sms"],
          phone_number: phoneNumber,
        }),
      }
    );
    const result = await response.json();
    return {
      status: response.status,
      oobCode: result.oob_code,
    };
  };
  const confirmSMS2FA = async (userCode: number, oobCode: string) => {
    "use server";
    const mfaToken: string = accessToken ?? "";

    const response = await fetch(
      `${process.env.AUTH0_ISSUER_BASE_URL}/oauth/token`,
      {
        method: "POST",
        headers: {
          Authorization: `Bearer ${mfaToken}`,
          "Content-Type": "application/x-www-form-urlencoded",
        },
        body: new URLSearchParams({
          grant_type: "http://auth0.com/oauth/grant-type/mfa-oob",
          client_id: process.env.AUTH0_CLIENT_ID || "",
          client_secret: process.env.AUTH0_CLIENT_SECRET || "",
          mfa_token: mfaToken,
          oob_code: oobCode,
          binding_code: userCode.toString(),
        }).toString(),
      }
    );

    const result = await response.json();
    const status = response.status;
    return { status: status, result: result };
  };

All works fine, but for some reason the access token gets expired after 5 minutues and the refresh token request fails because of the mfa_required.
I am not forcing the users to use MFA on login , I disabled it in the dashboard.
Also I wrote this action to make users that have active MFA use it on the login.

exports.onExecutePostLogin = async (event, api) => {
  if (event.user.enrolledFactors.find(m => m.type === 'phone')) {
    api.authentication.challengeWithAny([{ type: 'phone' }]);
  }
}

Please let me know how to handle the refresh token with the MFA.

Hi @rezgui.aziz,

It looks like your Action is challenging for MFA on every authentication (including refresh token use) with an existing phone factor. You will need to add a conditional here.

You can differentiate between the different types of requests (refresh token, normal login, etc.) in an Action via the event.transaction.protocol object.

Here’s a doc that has more info:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.