电子邮件与密码
电子邮件和密码认证是许多应用程序常用的方法。Better Auth 提供了一个内置的电子邮件和密码认证器,您可以轻松集成到您的项目中。
如果您更喜欢基于用户名的认证,请查看 用户名插件。它扩展了 电子邮件和密码认证器以支持用户名。
启用电子邮件和密码
要启用电子邮件和密码认证,您需要在 auth 配置中将 emailAndPassword.enabled 选项设置为 true。
import { betterAuth } from "better-auth";
export const auth = betterAuth({
emailAndPassword: {
enabled: true,
},
});如果未启用,则不允许使用电子邮件和 密码登录或注册。
使用方法
注册
要注册用户,您可以使用客户端提供的 signUp.email 函数。
const { data, error } = await authClient.signUp.email({ name: "John Doe", // required email: "john.doe@example.com", // required password: "password1234", // required image: "https://example.com/image.png", callbackURL: "https://example.com/callback",});| Prop | Description | Type |
|---|---|---|
name | 用户的姓名。 | string |
email | 用户的电子邮件地址。 | string |
password | 用户的密码。默认情况下应至少 8 个字符,最多 128 个。 | string |
image? | 用户的可选个人资料图片。 | string |
callbackURL? | 用户注册后重定向的可选 URL。 | string |
这些是注册电子邮件端点的默认属性,但是使用 附加字段 或特殊插件时,您可以向端点传递更多属性。
登录
要登录用户,您可以使用客户端提供的 signIn.email 函数。
const { data, error } = await authClient.signIn.email({ email: "john.doe@example.com", // required password: "password1234", // required rememberMe: true, callbackURL: "https://example.com/callback",});| Prop | Description | Type |
|---|---|---|
email | 用户的电子邮件地址。 | string |
password | 用户的密码。默认情况下应至少 8 个字符,最多 128 个。 | string |
rememberMe? | 如果为 false,则浏览器关闭时用户将被注销。(可选)(默认: true) | boolean |
callbackURL? | 用户登录后重定向的可选 URL。(可选) | string |
这些是登录电子邮件端点的默认属性,但是使用 附加字段 或特殊插件时,您可以向端点传递不同的属性。
注销
要注销用户,您可以使用客户端提供的 signOut 函数。
await authClient.signOut();您可以传递 fetchOptions 在成功时重定向
await authClient.signOut({
fetchOptions: {
onSuccess: () => {
router.push("/login"); // 重定向到登录页面
},
},
});电子邮件验证
要启用电子邮件验证,您需要传递一个发送包含链接的验证电子邮件的函数。sendVerificationEmail 函数接受一个数据对象,其中包含以下属性:
user: 用户对象。url: 发送给用户的包含令牌的 URL。token: 用于完成电子邮件验证的验证令牌。
以及作为第二个参数的 request 对象。
import { betterAuth } from "better-auth";
import { sendEmail } from "./email"; // 您的发送电子邮件函数
export const auth = betterAuth({
emailVerification: {
sendVerificationEmail: async ( { user, url, token }, request) => {
await sendEmail({
to: user.email,
subject: "验证您的电子邮件地址",
text: `点击链接验证您的电子邮件:${url}`,
});
},
},
});在客户端,您可以使用 sendVerificationEmail 函数向用户发送验证链接。这将触发您在 auth 配置中提供的 sendVerificationEmail 函数。
用户点击电子邮件中的链接后,如果令牌有效,用户将被重定向到 callbackURL 参数中提供的 URL。如果令牌无效,用户将被重定向到 callbackURL 参数中提供的 URL,并带有查询字符串中的错误消息 ?error=invalid_token。
要求电子邮件验证
如果您启用要求电子邮件验证,用户必须在登录前验证他们的电子邮件。而且每次用户尝试登录时,都会调用 sendVerificationEmail。
这仅在您实现了 sendVerificationEmail 并且用户 尝试使用电子邮件和密码登录时有效。
export const auth = betterAuth({
emailAndPassword: {
requireEmailVerification: true,
},
});如果用户未验证电子邮件而尝试登录,您可以处理错误并向用户显示消息。
await authClient.signIn.email(
{
email: "email@example.com",
password: "password",
},
{
onError: (ctx) => {
// 处理错误
if (ctx.error.status === 403) {
alert("请验证您的电子邮件地址");
}
// 您也可以显示原始错误消息
alert(ctx.error.message);
},
}
);手动触发电子邮件验证
您可以通过调用 sendVerificationEmail 函数手动触发电子邮件验证。
await authClient.sendVerificationEmail({
email: "user@email.com",
callbackURL: "/", // 验证后的重定向 URL
});请求密码重置
要允许用户重置密码,首先您需要向电子邮件和密码认证器提供 sendResetPassword 函数。sendResetPassword 函数接受一个数据对象,其中包含以下属性:
user: 用户对象。url: 发送给用户的包含令牌的 URL。token: 用于完成密码重置的验证令牌。
以及作为第二个参数的 request 对象。
import { betterAuth } from "better-auth";
import { sendEmail } from "./email"; // 您的发送电子邮件函数
export const auth = betterAuth({
emailAndPassword: {
enabled: true,
sendResetPassword: async ({user, url, token}, request) => {
await sendEmail({
to: user.email,
subject: "重置您的密码",
text: `点击链接重置您的密码:${url}`,
});
},
onPasswordReset: async ({ user }, request) => {
// 您的逻辑在这里
console.log(`用户 ${user.email} 的密码已被重置。`);
},
},
});此外,您可以提供一个 onPasswordReset 回调,在密码成功重置后执行逻辑。
配置服务器后,您可以调用 requestPasswordReset 函数向用户发送重置密码链接。如果用户存在,它将触发您在 auth 配置中提供的 sendResetPassword 函数。
const { data, error } = await authClient.requestPasswordReset({ email: "john.doe@example.com", // required redirectTo: "https://example.com/reset-password",});| Prop | Description | Type |
|---|---|---|
email | 发送密码重置电子邮件的用户电子邮件地址 | string |
redirectTo? | 重定向用户到重置密码的 URL。如果令牌无效或已过期,将重定向并带有查询参数 ?error=INVALID_TOKEN。如果令牌有效,将重定向并带有查询参数 `?token=VALID_TOKEN | string |
当用户点击电子邮件中的链接时,他们将被重定向到重置密码页面。您可以向您的应用程序添加重置密码页面。然后您可以使用 resetPassword 函数重置密码。它接受一个包含以下属性的对象:
newPassword: 用户的新密码。
const { data, error } = await authClient.resetPassword({
newPassword: "password1234",
token,
});const token = new URLSearchParams(window.location.search).get("token");if (!token) { // 处理错误}const { data, error } = await authClient.resetPassword({ newPassword: "password1234", // required token, // required});| Prop | Description | Type |
|---|---|---|
newPassword | 要设置的新密码 | string |
token | 重置密码的令牌 | string |
更新密码
用户的密码不存储在用户表中。相反,它存储在账户表中。要更改用户的密码,您可以使用以下方法之一:
const { data, error } = await authClient.changePassword({ newPassword: "newpassword1234", // required currentPassword: "oldpassword1234", // required revokeOtherSessions: true,});| Prop | Description | Type |
|---|---|---|
newPassword | 要设置的新密码 | string |
currentPassword | 当前用户密码 | string |
revokeOtherSessions? | 设置为 true 时,将使该用户的所有其他活动会话失效 | boolean |
配置
密码
Better Auth 将密码存储在 account 表中,并将 providerId 设置为 credential。
密码哈希:Better Auth 使用 scrypt 来哈希密码。scrypt 算法设计为缓慢且内存密集,以使攻击者难以对密码进行暴力破解。OWASP 推荐如果 argon2id 不可用,则使用 scrypt。我们决定使用 scrypt,因为它由 Node.js 原生支持。
您可以通过在 auth 配置中设置 passwordHasher 选项来传递自定义密码哈希算法。
import { betterAuth } from "better-auth"
import { scrypt } from "scrypt"
export const auth = betterAuth({
//...其他选项
emailAndPassword: {
password: {
hash: // 您的自定义密码哈希函数
verify: // 您的自定义密码验证函数
}
}
})| Prop | Type | Default |
|---|---|---|
enabled? | boolean | false |
disableSignUp? | boolean | false |
minPasswordLength? | number | 8 |
maxPasswordLength? | number | 128 |
sendResetPassword? | function | - |
onPasswordReset? | function | - |
resetPasswordTokenExpiresIn? | number | 3600 |
password? | object | - |