电子邮件 OTP
用于 Better Auth 的电子邮件 OTP 插件。
电子邮件 OTP 插件允许用户通过发送到其电子邮件地址的一次性密码(OTP)进行登录、验证电子邮件或重置密码。
安装
将插件添加到您的身份验证配置中
将 emailOTP 插件添加到您的身份验证配置,并实现 sendVerificationOTP() 方法。
import { betterAuth } from "better-auth"
import { emailOTP } from "better-auth/plugins"
export const auth = betterAuth({
// ... 其他配置选项
plugins: [
emailOTP({
async sendVerificationOTP({ email, otp, type }) {
if (type === "sign-in") {
// 发送登录的 OTP
} else if (type === "email-verification") {
// 发送电子邮件验证的 OTP
} else {
// 发送密码重置的 OTP
}
},
})
]
})添加客户端插件
import { createAuthClient } from "better-auth/client"
import { emailOTPClient } from "better-auth/client/plugins"
export const authClient = createAuthClient({
plugins: [
emailOTPClient()
]
})使用方法
发送 OTP
使用 sendVerificationOtp() 方法向用户的电子邮件地址发送 OTP。
const { data, error } = await authClient.emailOtp.sendVerificationOtp({ email: "user@example.com", // required type: "sign-in", // required});emailstringrequired发送 OTP 的电子邮件地址。
type"email-verification" | "sign-in" | "forget-password"requiredOTP 类型。sign-in、email-verification 或 forget-password。
校验 OTP(可选)
使用 checkVerificationOtp() 方法验证 OTP 是否有效。
const { data, error } = await authClient.emailOtp.checkVerificationOtp({ email: "user@example.com", // required type: "sign-in", // required otp: "123456", // required});emailstringrequired发送 OTP 的电子邮件地址。
type"email-verification" | "sign-in" | "forget-password"requiredOTP 类型。sign-in、email-verification 或 forget-password。
otpstringrequired发送到电子邮件的 OTP。
使用 OTP 登录
使用 OTP 登录时,先通过 sendVerificationOtp() 方法向用户电子邮件发送类型为 "sign-in" 的 OTP。
const { data, error } = await authClient.emailOtp.sendVerificationOtp({ email: "user@example.com", // required type: "sign-in", // required});emailstringrequired发送 OTP 的电子邮件地址。
type"sign-in"requiredOTP 类型。
用户提供 OTP 后,可使用 signIn.emailOtp() 方法登录用户。
const { data, error } = await authClient.signIn.emailOtp({ email: "user@example.com", // required otp: "123456", // required name: "John Doe", image: "https://example.com/image.png",});emailstringrequired登录的电子邮件地址。
otpstringrequired发送到电子邮件的 OTP。
namestring用户显示名称,仅在用户首次注册时使用。
imagestring用户头像 URL,仅在用户首次注册时使用。
使用 OTP 验证电子邮件
使用 OTP 验证用户邮箱时,先通过 sendVerificationOtp() 方法向用户邮箱发送类型为 "email-verification" 的 OTP。
const { data, error } = await authClient.emailOtp.sendVerificationOtp({ email: "user@example.com", // required type: "email-verification", // required});emailstringrequired发送 OTP 的电子邮件地址。
type"email-verification"requiredOTP 类型。
用户输入 OTP 后,使用 verifyEmail() 方法完成邮箱验证。
const { data, error } = await authClient.emailOtp.verifyEmail({ email: "user@example.com", // required otp: "123456", // required});emailstringrequired需要验证的电子邮件地址。
otpstringrequired需要验证的 OTP。
使用 OTP 重置密码
使用 OTP 重置密码时,使用 emailOtp.requestPasswordReset() 方法向用户邮箱发送类型为 "forget-password" 的 OTP。
const { data, error } = await authClient.emailOtp.requestPasswordReset({ email: "user@example.com", // required});emailstringrequired发送 OTP 的电子邮件地址。
/forget-password/email-otp 端点已被弃用,请改为使用 /email-otp/request-password-reset。
用户提供 OTP 后,可以选择使用 checkVerificationOtp() 方法验证 OTP 是否有效。
const { data, error } = await authClient.emailOtp.checkVerificationOtp({ email: "user@example.com", // required type: "forget-password", // required otp: "123456", // required});emailstringrequired发送 OTP 的电子邮件地址。
type"forget-password"requiredOTP 类型。
otpstringrequired发送到电子邮件的 OTP。
然后,使用 resetPassword() 方法重置用户密码。
const { data, error } = await authClient.emailOtp.resetPassword({ email: "user@example.com", // required otp: "123456", // required password: "new-secure-password", // required});emailstringrequired需要重置密码的电子邮件地址。
otpstringrequired发送到电子邮件的 OTP。
passwordstringrequired新密码。
使用 OTP 更改电子邮件
要允许用户使用 OTP 更改电子邮件,需先启用 changeEmail 功能,该功能默认关闭。将 changeEmail.enabled 设置为 true:
import { betterAuth } from "better-auth";
export const auth = betterAuth({
plugins: [
emailOTP({
changeEmail: {
enabled: true,
}
})
]
})默认情况下,当用户请求更改电子邮件时,OTP 会发送到新的电子邮件地址。只有用户验证了新邮箱后,邮箱才会被更新。
使用方法
要更改用户电子邮件地址,使用 emailOtp.requestEmailChange() 方法向用户新的电子邮件地址发送类型为 "change-email" 的 OTP。
const { data, error } = await authClient.emailOtp.requestEmailChange({ newEmail: "user@example.com", // required otp: "123456",});newEmailstringrequired新的电子邮件地址,用于接收 OTP。
otpstring发送到当前邮箱的 OTP。当 changeEmail.verifyCurrentEmail 选项设置为 true 时,此项必填。
用户提供 OTP 后,使用 changeEmail() 方法更改用户邮箱地址。
const { data, error } = await authClient.emailOtp.changeEmail({ newEmail: "user@example.com", // required otp: "123456", // required});newEmailstringrequired要更改为的新邮箱地址。
otpstringrequired发送到新邮箱的 OTP。
使用当前邮箱确认
为了增加安全性,您可以要求用户先通过发送到当前邮箱的 OTP 进行确认,再发送 OTP 到新邮箱。要启用此功能,请在插件选项中将 changeEmail.verifyCurrentEmail 设置为 true。
import { betterAuth } from "better-auth";
export const auth = betterAuth({
plugins: [
emailOTP({
changeEmail: {
enabled: true,
verifyCurrentEmail: true,
}
})
]
})在请求邮箱更改前,使用类型为 email-verification 的 sendVerificationOtp() 方法向用户邮箱发送 OTP。
const { data, error } = await authClient.emailOtp.sendVerificationOtp({ email: "user@example.com", // required type: "email-verification", // required});emailstringrequired发送 OTP 的电子邮件地址。
typestringrequiredOTP 类型。确认邮箱更改时必须为 email-verification。
然后,用户调用 requestEmailChange() 时提供该 OTP。系统会先验证发送到当前邮箱的 OTP,然后再发送 OTP 到新邮箱。
重写默认的电子邮件验证
要重写默认的电子邮件验证,可在选项中传入 overrideDefaultEmailVerification: true。此设置会让系统改用邮件 OTP 代替默认的验证链接来完成电子邮件验证。换言之,用户将通过输入 OTP 来验证邮箱,而不是点击链接。
import { betterAuth } from "better-auth";
import { emailOTP } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
emailOTP({
overrideDefaultEmailVerification: true,
async sendVerificationOTP({ email, otp, type }) {
// 实现 sendVerificationOTP 方法,向用户电子邮件发送 OTP
},
}),
],
});选项
-
sendVerificationOTP:向用户邮箱发送 OTP 的函数。该函数接收包含以下属性的对象:email:用户电子邮件地址。otp:生成的 OTP。type:OTP 类型,可为 "sign-in"、"email-verification" 或 "forget-password"。
建议不要等待邮件发送完成以避免时序攻击。在无服务器平台上,使用
waitUntil或类似方式确保邮件已发送。 -
otpLength:OTP 的长度。默认值为6。 -
expiresIn:OTP 过期时间(秒)。默认值为300秒。
import { betterAuth } from "better-auth"
import { emailOTP } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
emailOTP({
otpLength: 8,
expiresIn: 600
})
]
})-
sendVerificationOnSignUp:布尔值,决定用户注册时是否发送 OTP。默认值为false。 -
disableSignUp:布尔值,决定当用户未注册时是否禁止自动注册。默认值为false。 -
generateOTP:生成 OTP 的函数。默认生成一个随机 6 位数字。 -
allowedAttempts:允许验证 OTP 的最大尝试次数。默认值为3。超过该次数后,OTP 失效,用户需重新请求。
import { betterAuth } from "better-auth"
import { emailOTP } from "better-auth/plugins"
export const auth = betterAuth({
plugins: [
emailOTP({
allowedAttempts: 5, // 允许 5 次尝试后使 OTP 失效
expiresIn: 300
})
]
})当超过最大尝试次数时,verifyOTP、signIn.emailOtp、verifyEmail 和 resetPassword 方法将返回错误,错误码为 TOO_MANY_ATTEMPTS。
storeOTP:在数据库中存储 OTP 的方式,可选encrypted、hashed或plain文本。默认为明文存储。
注意:这不会影响发送给用户的 OTP,只影响数据库中存储的 OTP。
您也可以传入自定义的加密器或哈希器来存储 OTP。
自定义加密器
emailOTP({
storeOTP: {
encrypt: async (otp) => {
return myCustomEncryptor(otp);
},
decrypt: async (otp) => {
return myCustomDecryptor(otp);
},
}
})自定义哈希器
emailOTP({
storeOTP: {
hash: async (otp) => {
return myCustomHasher(otp);
},
}
})