> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Session-Based MFA

Session-Based MFA requires users to complete an MFA challenge on every login.

You can configure session-based MFA in the [Dynamic dashboard](https://app.dynamic.xyz/dashboard/security#accountmfa), by toggling on the "Session-based MFA" option.

You can also choose to make it mandatory or not, by toggling the "Require at onboarding" option.

## Required vs Optional

* Required
  If you make MFA required on onboarding, the user must have completed an MFA challenge on every login after this option is enabled.
  You, as a developer, will be responsible for checking if the user is missing MFA authentication and prompting them to complete an MFA challenge if required.

* Optional
  If you don't have MFA required on onboarding, the user will only be required to complete an MFA challenge on login if they have an MFA method registered.
  You, as a developer, will be responsible for checking if the user is missing MFA authentication and prompting them to complete an MFA challenge if required.

## Checking if a user is missing session-based MFA authentication

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    import { getMfaMethods, isUserMissingMfaAuth } from '@dynamic-labs-sdk/client';

    const onLogin = async () => {
      const isMissingMfaAuth = isUserMissingMfaAuth();

      if (!isMissingMfaAuth) {
        // you don't need to do anything here
        return;
      }

      // you should check if the has any registered MFA methods
      const mfaMethods = await getMfaMethods();
      const hasMfaMethods = mfaMethods.devices.length > 0 || mfaMethods.passkeys.length > 0;

      if (!hasMfaMethods) {
        // you should prompt the user to add a MFA method
      } else {
        // you should prompt the user to complete an MFA challenge
        // you can check the different methods they have registered and display the appropriate UI
      }
    };
    ```
  </Tab>

  <Tab title="React">
    `isUserMissingMfaAuth` is synchronous, so call it during render and read `useUser()` so the gate re-evaluates when user state changes (e.g. after the MFA challenge is completed). `useGetMfaMethods` loads the registered methods:

    ```tsx theme={"system"}
    import { isUserMissingMfaAuth } from '@dynamic-labs-sdk/client';
    import { useGetMfaMethods, useUser } from '@dynamic-labs-sdk/react-hooks';

    function SessionMfaGate({ children }: { children: React.ReactNode }) {
      const { data: user } = useUser(); // re-renders on userChanged
      const { data: mfaMethods } = useGetMfaMethods();

      if (!user) return null;
      if (!isUserMissingMfaAuth()) return <>{children}</>;
      if (!mfaMethods) return null; // loading

      const hasMfaMethods = mfaMethods.devices.length > 0 || mfaMethods.passkeys.length > 0;
      if (!hasMfaMethods) return <MfaSetupPrompt />;
      return <MfaChallengePrompt />;
    }
    ```
  </Tab>
</Tabs>

## Related functions

* [isUserMissingMfaAuth](/javascript/authentication-methods/is-user-missing-mfa-auth) - Check if user needs MFA authentication
* [isUserOnboardingComplete](/javascript/authentication-methods/is-user-onboarding-complete) - Check if user completed all onboarding requirements
* [Overview](/javascript/authentication-methods/mfa/overview)
* [Action-Based MFA](/javascript/authentication-methods/mfa/action-based)
* [Passkeys](/javascript/authentication-methods/mfa/passkey)
* [Authenticator Apps](/javascript/authentication-methods/mfa/totp)
* [Recovery Codes](/javascript/authentication-methods/mfa/recovery-codes)
