两因素认证 (2FA)
什么是两因素认证 (2FA)?
两因素认证(2FA)是一种安全机制,它要求用户在登录时提供两种不同类型的身份验证因素。这通常包括"你知道的东西"(如密码)和"你拥有的东西"(如手机或安全密钥)。通过要求多重验证步骤,2FA显著提高了账户安全性,即使密码被泄露,未授权用户也难以访问账户。
Better Auth的2FA插件支持多种验证方法,包括基于时间的一次性密码(TOTP)和一次性密码(OTP),让你能够为用户提供强大而灵活的安全选项。
此插件提供两种主要方法来进行第二因素验证:
- OTP(一次性密码):发送到用户电子邮件或手机的临时代码。
- TOTP(基于时间的一次性密码):由用户设备上的应用程序生成的代码。
附加功能包括:
- 生成账户恢复的备份码
- 启用/禁用 2FA
- 管理可信设备
安装
使用方法
启用 2FA
要启用两因素认证,请调用 twoFactor.enable
并提供用户密码和发行者(可选):
启用 2FA 时:
- 会生成加密的
secret
和backupCodes
。 enable
返回totpURI
和backupCodes
。
注意:在用户验证其 TOTP 代码之前,twoFactorEnabled
不会设置为 true
。
要验证,请显示二维码供用户使用认证器应用扫描。用户输入代码后,调用 verifyTotp
:
你可以通过在插件配置中设置 skipVerificationOnEnable
为 true 来跳过验证。
使用 2FA 登录
当启用了 2FA 的用户尝试通过电子邮件登录时,响应将包含 twoFactorRedirect
设置为 true
。这表示用户需要验证其 2FA 代码。
你可以在 onSuccess
回调中处理此情况,或者通过在插件配置中提供 onTwoFactorRedirect
回调来处理。
或者你可以在当前位置处理:
使用 auth.api
当你在服务器上调用 auth.api.signInEmail
,并且用户启用了 2FA,它默认会返回一个 twoFactorRedirect
设置为 true
的对象。这种行为在 TypeScript 中没有被推断出来,这可能会产生误导。我们建议传递 asResponse: true
以获取 Response 对象。
禁用 2FA
要禁用两因素认证,请调用 twoFactor.disable
并提供用户密码:
TOTP
TOTP(基于时间的一次性密码)是一种算法,它使用时间作为计数器为每次登录尝试生成唯一密码。每个固定间隔(Better Auth 默认为 30 秒),都会生成一个新密码。这解决了传统密码的几个问题:它们可能被忘记、被盗或被猜测。OTP 解决了其中一些问题,但它们通过短信或电子邮件的传递可能不可靠(或者甚至有风险,考虑到它打开了新的攻击向量)。
然而,TOTP 离线生成代码,使其既安全又方便。你只需要在手机上安装一个认证器应用,就可以了——不需要互联网。
获取 TOTP URI
启用 2FA 后,你可以获取 TOTP URI 显示给用户。此 URI 由服务器使用 secret
和 issuer
生成,可用于生成二维码供用户使用认证器应用扫描。
示例:使用 React
默认情况下,TOTP 的发行者设置为认证配置中提供的应用名称,如果未提供,则设置为 Better Auth
。你可以通过在插件配置中传递 issuer
来覆盖此设置。
验证 TOTP
用户输入其 2FA 代码后,你可以使用 twoFactor.verifyTotp
方法进行验证。
OTP
OTP(一次性密码)类似于 TOTP,但是会生成随机代码并发送到用户的电子邮件或手机。
在使用 OTP 验证第二因素之前,你需要在 Better Auth 实例中配置 sendOTP
。此函数负责将 OTP 发送到用户的电子邮件、手机或应用程序支持的任何其他方法。
发送 OTP
通过调用 twoFactor.sendOtp
函数发送 OTP。此函数将触发你在 Better Auth 配置中提供的 sendOTP 实现。
验证 OTP
用户输入 OTP 代码后,你可以验证它
备份码
备份码在数据库中生成和存储。如果用户失去对手机或电子邮件的访问权限,这可以用于恢复对账户的访问权限。
生成备份码
为账户恢复生成备份码:
使用备份码
现在你可以允许用户提供备份码作为账户恢复方法。
一旦使用了备份码,它将从数据库中删除,不能再次使用。
查看备份码
你可以随时通过调用 viewBackupCodes
查看备份码。此操作只能在服务器上使用 auth.api
执行。
可信设备
你可以通过在 verifyTotp
或 verifyOtp
中传递 trustDevice
将设备标记为可信。
当 trustDevice
设置为 true
时,当前设备将被记住 60 天。在此期间,用户在后续从此设备登录时不会被要求提供 2FA。每次用户成功登录时,信任期都会刷新。
发行者
通过添加 issuer
,你可以为 2fa 应用程序设置你的应用程序名称。
例如,如果你的用户使用 Google Auth,默认的 appName 将显示为 Better Auth
。然而,通过使用以下代码,它将显示为 my-app-name
。
schema
该插件需要在 user
表中添加 1 个附加字段,并添加 1 个额外的表来存储两因素认证数据。
Field Name | Type | Key | Description |
---|---|---|---|
twoFactorEnabled | boolean | 用户是否启用了两因素认证。 |
表:twoFactor
Field Name | Type | Key | Description |
---|---|---|---|
id | string | 两因素认证的 id。 | |
userId | string | 用户的 id | |
secret | string | 用于生成 TOTP 代码的密钥。 | |
backupCodes | string | 如果用户失去对手机或电子邮件的访问权限,用于恢复账户访问的备份码。 |
选项
服务器
twoFactorTable:存储两因素认证数据的表名。默认:twoFactor
。
skipVerificationOnEnable:在为用户启用两因素之前跳过验证过程。
Issuer:发行者是你的应用程序的名称。它用于生成 TOTP 代码。它将显示在认证器应用程序中。
TOTP 选项
这些是 TOTP 的选项。
Prop | Type | Default |
---|---|---|
digits? | number | 6 |
period? | number | 30 |
OTP 选项
这些是 OTP 的选项。
Prop | Type | Default |
---|---|---|
sendOTP? | function | - |
period? | number | 30 |
备份码选项
当用户启用两因素认证时,备份码会在数据库中生成和存储。如果用户失去对手机或电子邮件的访问权限,可以用于恢复对账户的访问权限。
Prop | Type | Default |
---|---|---|
amount? | number | 10 |
length? | number | 10 |
customBackupCodesGenerate? | function | - |
客户端
要在客户端使用两因素插件,你需要将其添加到你的插件列表中。
选项
onTwoFactorRedirect
:当用户需要验证其 2FA 代码时将调用的回调。这可用于将用户重定向到 2FA 页面。