Two Factor Authentication Best Practices

Configure TOTP authenticator apps, send OTP codes via email/SMS, manage backup codes, handle trusted devices, and implement 2FA sign-in flows using

What Is This?

Overview

Two factor authentication (2FA) adds a second verification step to the login process, requiring users to confirm their identity with something they own or know beyond a password. Better Auth's twoFactor plugin provides a complete implementation layer that handles TOTP authenticator apps, OTP delivery via email or SMS, backup codes, trusted device management, and full 2FA sign-in flows within a single cohesive system.

The plugin integrates directly into your existing Better Auth server and client configuration, meaning you do not need to wire together separate libraries or build custom middleware to support multi-factor authentication. The setup follows a predictable pattern: configure the server plugin with an issuer name, add the client plugin, run the database migration, and begin calling the provided methods from your application code.

Security requirements for modern applications increasingly include MFA as a baseline expectation rather than an optional feature. Whether you are building a SaaS product, an internal tool, or a consumer application, implementing 2FA through a well-structured plugin reduces the risk of account compromise from credential leaks and phishing attacks.

Who Should Use This

  • Backend developers building authentication systems with Better Auth who need to add MFA without assembling multiple packages
  • Frontend engineers implementing login flows that require a second verification step after password entry
  • Security-focused teams that need backup code management and trusted device handling as part of their authentication requirements
  • Full-stack developers who want TOTP and OTP support delivered through a single plugin interface
  • Product teams shipping applications where regulatory or compliance requirements mandate multi-factor authentication
  • Developers migrating from custom 2FA implementations who want a standardized, maintainable approach

Why Use It?

Problems It Solves

  • Passwords alone are insufficient protection against credential stuffing, phishing, and data breach reuse, and adding a second factor closes the most common account takeover vectors
  • Building TOTP generation, QR code provisioning, OTP delivery, and backup code logic from scratch is time-consuming and error-prone without a structured plugin
  • Managing trusted devices across sessions requires careful state handling that the plugin abstracts into straightforward method calls
  • Coordinating the multi-step sign-in flow, where a user passes password verification and then enters a 2FA code, involves conditional routing logic that the plugin standardizes
  • Handling backup codes securely, including hashing, single-use enforcement, and regeneration, is handled automatically rather than requiring custom database logic

Core Highlights

  • TOTP support compatible with Google Authenticator, Authy, and any RFC 6238 compliant app
  • OTP delivery via email and SMS for users who prefer not to use an authenticator app
  • Backup code generation and management with secure single-use enforcement
  • Trusted device registration to reduce friction for recognized browsers or devices
  • Full sign-in flow management covering the transition from password verification to 2FA challenge
  • Database schema generation via a single CLI migration command
  • Client and server plugins that share a consistent API surface

How to Use It?

Basic Usage

Add the plugin to your server configuration with an issuer name that will appear in authenticator apps:

import { betterAuth } from "better-auth";
import { twoFactor } from "better-auth/plugins";

export const auth = betterAuth({
  plugins: [
    twoFactor({ issuer: "MyApp" })
  ]
});

Add the client plugin to your frontend configuration:

import { createAuthClient } from "better-auth/client";
import { twoFactorClient } from "better-auth/plugins/client";

export const authClient = createAuthClient({
  plugins: [twoFactorClient()]
});

Run the database migration to create the required tables:

npx @better-auth/cli migrate

Specific Scenarios

Enabling TOTP for a user: After a user opts into 2FA, call the TOTP setup method to generate a QR code URI, display it in your UI, and confirm activation once the user submits a valid code from their authenticator app.

Handling the 2FA challenge during sign-in: After successful password verification, check whether the user has 2FA enabled. If so, redirect to a challenge screen and call the verification method with the submitted code before completing the session.

Real-World Examples

A SaaS dashboard can gate access to billing and team management pages behind a 2FA prompt, requiring re-verification even for authenticated sessions. An internal admin tool can enforce TOTP enrollment as a prerequisite for accessing sensitive configuration panels.

Important Notes

Requirements

  • Better Auth must already be configured with a working database connection before adding the twoFactor plugin
  • The CLI migration command must be run after adding the plugin to create the necessary schema tables
  • Email or SMS OTP delivery requires a configured transport provider such as an SMTP service or SMS gateway