Multi-Factor Authentication (MFA)
Learn how to add TOTP-based multi-factor authentication to your application for enhanced security.
MFA TOTP two-factor 2FA authenticator security multi-factorMulti-Factor Authentication adds an extra layer of security by requiring a verification code from an authenticator app (e.g., Authy, Google Authenticator) in addition to the user’s email and password.
Configuration
Section titled “Configuration”To enable MFA, navigate to Settings -> Authentication and enable Multi-Factor Authentication. You can also configure it using the nhost.toml file:
[auth.totp]enabled = trueEnabling MFA
Section titled “Enabling MFA”Once MFA is enabled for your project, individual users can activate it on their account. This is a two-step process:
Step 1: Generate TOTP Secret
Section titled “Step 1: Generate TOTP Secret”Request a TOTP secret and QR code for the user to scan with their authenticator app:
const response = await nhost.auth.changeUserMfa();
// Display the QR code image for the user to scanconst imageUrl = response.body.imageUrl;// Or show the totpSecret for manual entryconst totpSecret = response.body.totpSecret;Step 2: Verify and Activate
Section titled “Step 2: Verify and Activate”After the user scans the QR code, they enter the 6-digit verification code from their authenticator app to confirm activation:
await nhost.auth.verifyChangeUserMfa({ activeMfaType: 'totp', code: '123456', // 6-digit code from authenticator app});Activation Flow
Section titled “Activation Flow”sequenceDiagram autonumber actor U as User participant C as Client participant A as Nhost Auth participant G as Authenticator App U-->A: Authenticated C->>+A: GET /mfa/totp/generate A->>-C: QR code image URL + TOTP secret C->>U: Display QR code U->>+G: Scan QR code G->>-U: 6-digit TOTP code C->>+A: POST /user/mfa Note right of C: TOTP code + activeMfaType: "totp" A->>A: Verify code and activate MFA A->>-C: OKSigning In with MFA
Section titled “Signing In with MFA”When a user with MFA enabled signs in with email and password, the server returns a ticket instead of a session. The client must then prompt for a TOTP code and verify it to complete sign-in.
Step 1: Initial Sign-In
Section titled “Step 1: Initial Sign-In”const response = await nhost.auth.signInEmailPassword({ email: 'joe@example.com', password: 'secret-password',});
if (response.body?.mfa) { // MFA is required — store the ticket and prompt for TOTP const ticket = response.body.mfa.ticket; // Navigate to MFA verification page}Step 2: Verify TOTP Code
Section titled “Step 2: Verify TOTP Code”const response = await nhost.auth.verifySignInMfaTotp({ ticket: ticket, // from step 1 otp: '123456', // 6-digit code from authenticator app});
// response.body.session contains the access + refresh tokensSign-In with MFA Flow
Section titled “Sign-In with MFA Flow”sequenceDiagram autonumber actor U as User participant C as Client participant A as Nhost Auth participant G as Authenticator App U->>C: Enter email + password C->>+A: POST /signin/email-password A->>-C: MFA ticket C->>U: Prompt for TOTP code U->>+G: Open authenticator app G->>-U: 6-digit TOTP code U->>C: Enter TOTP code C->>+A: POST /signin/mfa/totp Note right of C: ticket + TOTP code A->>A: Verify TOTP A->>-C: Session (access + refresh tokens)Disabling MFA
Section titled “Disabling MFA”Users can disable MFA by providing a current TOTP code from their authenticator app:
await nhost.auth.verifyChangeUserMfa({ activeMfaType: '', // empty string disables MFA code: '123456', // current 6-digit code from authenticator app});