The two-factor authentication (2FA) plugin adds a second verification step after a user signs in with their password. It supports:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/better-auth/better-auth/llms.txt
Use this file to discover all available pages before exploring further.
- TOTP — time-based codes from an authenticator app (Google Authenticator, Authy, etc.)
- OTP — one-time codes sent to the user’s email or phone
- Backup codes — single-use recovery codes
- Trusted devices — skip 2FA on recognized devices for 30 days
Installation
Add the server plugin
Import
twoFactor and add it to your plugins list. Set appName to customize the issuer shown in authenticator apps:auth.ts
Run the database migration
The plugin adds a
twoFactorEnabled column to the user table and creates a twoFactor table:- migrate
- generate
Usage
Enable 2FA for a user
CalltwoFactor.enable with the user’s current password. The server generates a TOTP secret and backup codes:
enable-2fa.ts
Display a QR code
Use thetotpURI to render a scannable QR code:
two-factor-setup.tsx
Verify a TOTP code
After the user scans the QR code, verify the first code to confirm setup:verify-totp.ts
Sign in with 2FA enabled
When a user with 2FA enabled signs in, the response includestwoFactorRedirect: true. Handle it in the onSuccess callback:
sign-in.ts
Disable 2FA
disable-2fa.ts
OTP (email or SMS)
Instead of TOTP, you can send a one-time code via email or phone. ConfigureotpOptions.sendOTP on the server:
auth.ts
Send an OTP
send-otp.ts
Verify an OTP
verify-otp.ts
Backup codes
Backup codes are generated when 2FA is enabled. Each code can only be used once.Generate new backup codes
generate-backup-codes.ts
Verify a backup code
verify-backup-code.ts
Trusted devices
PasstrustDevice: true when verifying any 2FA method to skip 2FA for 30 days on that device:
verify-with-trust.ts
Configuration options
Server options
| Option | Type | Default | Description |
|---|---|---|---|
issuer | string | app name | Issuer name shown in authenticator apps. Overrides appName. |
skipVerificationOnEnable | boolean | false | Set true to mark 2FA enabled without requiring a TOTP verification. |
twoFactorTable | string | "twoFactor" | Custom table name for storing 2FA data. |
otpOptions.sendOTP | function | — | Send an OTP code to the user. |
otpOptions.period | number | 3 | OTP validity period in minutes. |
totpOptions.digits | number | 6 | Number of digits in the TOTP code. |
totpOptions.period | number | 30 | TOTP window in seconds. |
backupCodeOptions.amount | number | 10 | Number of backup codes to generate. |
backupCodeOptions.length | number | 10 | Length of each backup code. |
Client options
| Option | Type | Description |
|---|---|---|
twoFactorPage | string | URL to redirect users who need to complete 2FA. Causes a full page reload. |
onTwoFactorRedirect | function | Callback for handling the 2FA redirect programmatically. |