Two-Factor Authentication (2FA)
OTP
TOTP
Backup Codes
Trusted Devices
Two-Factor Authentication (2FA) adds an extra security step when users log in. Instead of just using a password, they'll need to provide a second form of verification. This makes it much harder for unauthorized people to access accounts, even if they've somehow gotten the password.
This plugin offers two main methods to do a second factor verification:
- OTP (One-Time Password): A temporary code sent to the user's email or phone.
- TOTP (Time-based One-Time Password): A code generated by an app on the user's device.
Additional features include:
- Generating backup codes for account recovery
- Enabling/disabling 2FA
- Managing trusted devices
Installation
Add the plugin to your auth config
Add the two-factor plugin to your auth configuration and specify your app name as the issuer.
Migrate the database
Run the migration or generate the schema to add the necessary fields and tables to the database.
See the Schema section to add the fields manually.
Add the client plugin
Add the client plugin and Specify where the user should be redirected if they need to verify 2nd factor
Usage
Enabling 2FA
To enable two-factor authentication, call twoFactor.enable
with the user's password:
When 2FA is enabled:
- An encrypted
secret
andbackupCodes
are generated. enable
returnstotpURI
andbackupCodes
.
Note: twoFactorEnabled
won’t be set to true
until the user verifies their TOTP code.
To verify, display the QR code for the user to scan with their authenticator app. After they enter the code, call verifyTotp
:
You can skip verification by setting skipVerificationOnEnable
to true in your plugin config.
Sign In with 2FA
When a user with 2FA enabled tries to sign in via email, they will be redirected to the twoFactorPage
(specified in your client config) unless they're using a trusted device.
By default, if a user has 2FA enabled, they will be redirected to the twoFactorPage
. If you want to manage the 2FA verification directly within your application instead, simply pass redirect:false
to the client plugin and handle the verification in the callback.
Using auth.api
When you call auth.api.signInEmail
on the server, and the user has 2FA enabled, it will, by default, respond with an object where twoFactorRedirect
is set to true
. This behavior isn’t inferred in TypeScript, which can be misleading. We recommend passing asResponse: true
to receive the Response object instead.
s
TOTP
TOTP (Time-Based One-Time Password) is an algorithm that generates a unique password for each login attempt using time as a counter. Every fixed interval (Better Auth deafults to 30 seconds), a new password is generated. This addresses several issues with traditional passwords: they can be forgotten, stolen, or guessed. OTPs solve some of these problems, but their delivery via SMS or email can be unreliable (or even risky, considering it opens new attack vectors).
TOTP, however, generates codes offline, making it both secure and convenient. You just need an authenticator app on your phone, and you’re set—no internet required.
Getting TOTP URI
After enabling 2FA, you can get the TOTP URI to display to the user. This URI is generated by the server using the secret
and issuer
and can be used to generate a QR code for the user to scan with their authenticator app.
Example: Using React
By default the issuer for TOTP is set to the app name provided in the auth config or if not provided it will be set to Better Auth
. You can override this by passing issuer
to the plugin config.
Verifying TOTP
After the user has entered their 2FA code, you can verify it using twoFactor.verifyTotp
method.
OTP
OTP (One-Time Password) is similar to TOTP but the code is sent directly to the user, and the code is valid for 3 mins by default.
Before using OTP to verify the second factor, you need to configure sendOTP
in your Better Auth instance. This function is responsible for sending the OTP to the user's email, phone, or any other method supported by your application.
Sending OTP
Sending an OTP is done by calling the twoFactor.sendOtp
function. This function will trigger your sendOTP implementation that you provided in the Better Auth configuration.
Verifying OTP
After the user has entered their OTP code, you can verify it
Backup Codes
Backup codes are generated and stored in the database. This can be used to recover access to the account if the user loses access to their phone or email.
Generating Backup Codes
Generate backup codes for account recovery:
Using Backup Codes
You can now allow users to provider backup code as account recover method.
once a backup code is used, it will be removed from the database and can't be used again.
Viewing Backup Codes
You can view the backup codes at any time by calling viewBackupCodes
. This action can only be performed on the server using auth.api
.
Trusted Devices
You can mark a device as trusted by passing trustDevice
to verifyTotp
or verifyOtp
.
When trustDevice
is set to true
, the current device will be remembered for 60 days. During this period, the user won't be prompted for 2FA on subsequent sign-ins from this device. The trust period is refreshed each time the user signs in successfully.
Schema
The plugin requires 1 additional fields in the user
table and 1 additional table to store the two factor authentication data.
Field Name | Type | Key | Description |
---|---|---|---|
twoFactorEnabled | boolean | Whether two factor authentication is enabled for the user. |
Table: twoFactor
Field Name | Type | Key | Description |
---|---|---|---|
secret | string | The secret used to generate the TOTP code. | |
backupCodes | string | The backup codes used to recover access to the account if the user loses access to their phone or email. |
Options
Server
twoFactorTable: The name of the table that stores the two factor authentication data. Default: twoFactor
.
skipVerificationOnEnable: Skip the verification process before enabling two factor for a user.
Issuer: The issuer is the name of your application. It's used to generate TOTP codes. It'll be displayed in the authenticator apps.
TOTP options
these are options for TOTP.
Prop | Type | Default |
---|---|---|
digits | number | 6 |
period | number | 30 |
OTP options
these are options for OTP.
Prop | Type | Default |
---|---|---|
sendOTP | function | - |
period | number | 30 |
Backup Code Options
backup codes are generated and stored in the database when the user enabled two factor authentication. This can be used to recover access to the account if the user loses access to their phone or email.
Prop | Type | Default |
---|---|---|
amount | number | 10 |
length | number | 10 |
customBackupCodesGenerate | function | - |
Client
To use the two factor plugin in the client, you need to add it on your plugins list.
Options
twoFactorPage
: The page to redirect the user to after they have enabled 2-Factor. This is the page where the user will be redirected to verify their 2-Factor code.
redirect
: If set to false
, the user will not be redirected to the twoFactorPage
after they have enabled 2-Factor.