邮件
了解如何设置邮件验证、要求登录时使用已验证的邮件地址、在验证后自动登录、处理验证后的回调,以及实现密码重置邮件。
邮件是 Better Auth 的关键部分,所有用户无论使用何种认证方式都必须使用邮件。Better Auth 开箱即用提供邮件和密码认证,并提供了很多工具帮助你管理邮件验证、密码重置等功能。
自带电子邮件服务商
Better Auth 可与任何事务性电子邮件服务商配合使用,让您完全掌控身份验证邮件的发送方式。要发送邮件,请先设置您偏好的服务商。
例如,你可以考虑以下邮件服务商:
邮件验证
在你的应用中添加邮件验证
要启用邮件验证,你需要传入一个发送验证邮件的函数,该邮件带有一个链接。
- sendVerificationEmail:当邮件验证启动时触发的函数。它接收一个包含以下属性的数据对象:
user:包含邮件地址的用户对象。url:用户必须点击以验证邮件的验证链接。token:验证令牌,用于完成邮件验证,可用于自定义验证链接的实现。
- sendVerificationEmail:当邮件验证启动时触发的函数。它接收一个包含以下属性的数据对象:
user:包含邮件地址的用户对象。url:用户必须点击以验证邮件的验证 URL。token:用于完成邮件验证的验证令牌,可在实现自定义验证 URL 时使用。
以及作为第二个参数传入的 request 对象。
import { betterAuth } from 'better-auth';
import { sendEmail } from './email'; // 你的邮件发送函数
export const auth = betterAuth({
emailVerification: {
sendVerificationEmail: async ({ user, url, token }, request) => {
void sendEmail({
to: user.email,
subject: '验证你的邮件地址',
text: `点击链接验证你的邮件:${url}`
})
}
}
})避免等待邮件发送完成,以防止时序攻击。在无服务器平台上,请使用 waitUntil 或类似方法来确保邮件发送成功。
触发邮件验证
你可以通过多种方式触发邮件验证:
1. 注册时
要在注册时自动发送验证邮件,请将 emailVerification.sendOnSignUp 设置为 true。
import { betterAuth } from 'better-auth';
export const auth = betterAuth({
emailVerification: {
sendOnSignUp: true
}
})这样用户注册时会发送验证邮件。对于社交登录,邮件验证状态会从 SSO 读取。
启用 sendOnSignUp 后,当用户使用未声明邮件已验证的 SSO 登录时,Better Auth 会发送验证邮件,但即使启用了 requireEmailVerification,用户仍然无需验证邮件即可登录。
2. 强制邮件验证
如果启用强制邮件验证,用户必须验证邮件后才能登录。每次用户尝试登录时,都会调用 sendVerificationEmail。
只有在实现了 sendVerificationEmail、将 sendOnSignIn 设置为 true,并且用户尝试使用邮件和密码登录时,此功能才会生效。
import { betterAuth } from "better-auth";
import { sendEmail } from './email'; // 你的邮件发送函数
export const auth = betterAuth({
emailVerification: {
sendVerificationEmail: async ({ user, url }) => {
void sendEmail({
to: user.email,
subject: "验证你的邮件地址",
text: `点击链接验证你的邮件:${url}`,
});
},
sendOnSignIn: true,
},
emailAndPassword: {
requireEmailVerification: true,
},
});如果用户尝试在未验证邮件的情况下登录,你可以捕获错误并向用户显示提示。
await authClient.signIn.email({
email: "[email protected]",
password: "password"
}, {
onError: (ctx) => {
// 处理错误
if(ctx.error.status === 403) {
alert("请验证你的邮件地址")
}
// 你也可以显示原始错误消息
alert(ctx.error.message)
}
})3. 手动触发
你也可以通过调用 sendVerificationEmail 手动触发邮件验证。
await authClient.sendVerificationEmail({
email: "[email protected]",
callbackURL: "/" // 验证后重定向的 URL
})验证邮件
如果用户点击验证链接,他们的邮件会被自动验证,并被重定向至 callbackURL。
对于手动验证,你可以发送带有 token 的自定义链接给用户,然后调用 verifyEmail 方法。
await authClient.verifyEmail({
query: {
token: "" // 在这里传递令牌
}
})验证后自动登录
若你希望用户成功验证邮件后自动登录,请将 autoSignInAfterVerification 选项设置为 true:
import { betterAuth } from "better-auth";
const auth = betterAuth({
//... 其他配置
emailVerification: {
autoSignInAfterVerification: true
}
})验证前回调
你可以使用 beforeEmailVerification 回调,在用户邮件被标记为已验证之前运行自定义代码。这对于验证、预检查或在最终确定验证之前准备数据非常有用。
import { betterAuth } from 'better-auth';
export const auth = betterAuth({
emailVerification: {
async beforeEmailVerification(user, request) {
// 运行验证前逻辑
console.log(`About to verify ${user.email}`);
}
}
})验证成功后回调
你可以使用 afterEmailVerification 回调,在用户成功验证邮件后立即执行自定义代码。这对于触发副作用非常有用,比如授予特殊权限或记录日志。
afterEmailVerification 函数会在用户邮件确认时自动调用,接收 user 对象和 request 详情,以便你针对特定用户执行操作。
示例如下:
import { betterAuth } from 'better-auth';
export const auth = betterAuth({
emailVerification: {
async afterEmailVerification(user, request) {
// 你的自定义逻辑,例如授予高级功能访问权限
console.log(`${user.email} 已成功验证!`);
}
}
})重复注册尝试回调
当有人尝试使用已经存在的邮箱注册时,会触发 onExistingUserSignUp 回调。这对于通知现有用户有人尝试使用他们的邮箱地址注册非常有用。
仅当 emailAndPassword.requireEmailVerification 设置为 true 时,才会调用此回调。此设置会启用通用重复响应(合成用户),而不是抛出邮箱重复错误。
import { betterAuth } from 'better-auth';
export const auth = betterAuth({
emailAndPassword: {
enabled: true,
onExistingUserSignUp: async ({ user }, request) => {
// 通知现有用户有人尝试使用他们的邮箱注册
console.log(`Someone tried to sign up with ${user.email}`);
}
}
})密码重置邮件
忘记密码时,重置密码功能允许用户重设密码。Better Auth 提供了简单的方式实现密码重置。
你可以通过传入发送密码重置邮件的函数来启用密码重置功能,该邮件带有一个链接。
import { betterAuth } from 'better-auth';
import { sendEmail } from './email'; // 你的邮件发送函数
export const auth = betterAuth({
emailAndPassword: {
enabled: true,
sendResetPassword: async ({ user, url, token }, request) => {
void sendEmail({
to: user.email,
subject: '重置你的密码',
text: `点击链接重置你的密码:${url}`
})
}
}
})避免等待邮件发送完成,以防止计时攻击。在无服务器平台上,请使用 waitUntil 或类似机制来确保邮件能够发送。
更多关于如何在应用中实现密码重置的信息,请查看 邮件和密码 指南。 你也可以参阅 OTP 验证 指南,了解如何用 OTP 实现密码重置。