Skip to main content
The two-factor authentication (2FA) plugin adds a second verification step after a user signs in with their password. It supports:
  • 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

1

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
2

Run the database migration

The plugin adds a twoFactorEnabled column to the user table and creates a twoFactor table:
3

Add the client plugin

Import twoFactorClient and configure where to redirect users who need to complete 2FA:
auth-client.ts
Using twoFactorPage causes a full page reload when redirecting. Use onTwoFactorRedirect to handle the redirect programmatically and avoid a reload.

Usage

Enable 2FA for a user

Call twoFactor.enable with the user’s current password. The server generates a TOTP secret and backup codes:
enable-2fa.ts
twoFactorEnabled is not set to true until the user verifies a TOTP code. This ensures the user has successfully scanned the QR code before 2FA is enforced. You can skip this requirement by setting skipVerificationOnEnable: true in the plugin config.

Display a QR code

Use the totpURI 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
Better Auth accepts TOTP codes from the current 30-second window, plus one window before and after, to account for clock drift.

Sign in with 2FA enabled

When a user with 2FA enabled signs in, the response includes twoFactorRedirect: 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. Configure otpOptions.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
Generating new backup codes permanently deletes the old ones.

Verify a backup code

verify-backup-code.ts

Trusted devices

Pass trustDevice: true when verifying any 2FA method to skip 2FA for 30 days on that device:
verify-with-trust.ts

Configuration options

Server options

Client options