Hooks
Better Auth 中的钩子让您“钩入”生命周期并执行自定义逻辑。它们提供了一种自定义 Better Auth 行为的方式,而无需编写完整的插件。
我们强烈推荐使用钩子,如果您需要对端点进行自定义调整,而不是在 Better Auth 外部创建另一个端点。
前置钩子
前置钩子 在端点执行 之前 运行。使用它们来修改请求、预验证数据,或提前返回。
示例:强制执行电子邮件域名限制
此钩子确保用户只能在电子邮件以 @example.com 结尾时注册:
import { betterAuth } from "better-auth";
import { createAuthMiddleware, APIError } from "better-auth/api";
export const auth = betterAuth({
hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path !== "/sign-up/email") {
return;
}
if (!ctx.body?.email.endsWith("@example.com")) {
throw new APIError("BAD_REQUEST", {
message: "Email must end with @example.com",
});
}
}),
},
});示例:修改请求上下文
在继续之前调整请求上下文:
import { betterAuth } from "better-auth";
import { createAuthMiddleware } from "better-auth/api";
export const auth = betterAuth({
hooks: {
before: createAuthMiddleware(async (ctx) => {
if (ctx.path === "/sign-up/email") {
return {
context: {
...ctx,
body: {
...ctx.body,
name: "John Doe",
},
}
};
}
}),
},
});后置钩子
后置钩子 在端点执行 之后 运行。使用它们来修改响应。
示例:当新用户注册时向您的频道发送通知
import { betterAuth } from "better-auth";
import { createAuthMiddleware } from "better-auth/api";
import { sendMessage } from "@/lib/notification"
export const auth = betterAuth({
hooks: {
after: createAuthMiddleware(async (ctx) => {
if(ctx.path.startsWith("/sign-up")){
const newSession = ctx.context.newSession;
if(newSession){
sendMessage({
type: "user-register",
name: newSession.user.name,
})
}
}
}),
},
});Ctx
当您调用 createAuthMiddleware 时,会传递一个 ctx 对象,它提供了许多有用的属性。包括:
- 路径:
ctx.path用于获取当前端点路径。 - 请求体:
ctx.body用于解析的请求体(仅适用于 POST 请求)。 - 头部:
ctx.headers用于访问请求头部。 - 请求:
ctx.request用于访问请求对象(在仅服务器端点中可能不存在)。 - 查询参数:
ctx.query用于访问查询参数。 - 上下文:
ctx.context认证相关上下文,用于访问新会话、认证 Cookie 配置、密码哈希、配置等...
以及更多。
请求响应
此实用工具允许您从钩子中获取请求信息并发送响应。
JSON 响应
使用 ctx.json 发送 JSON 响应:
const hook = createAuthMiddleware(async (ctx) => {
return ctx.json({
message: "Hello World",
});
});重定向
使用 ctx.redirect 重定向用户:
import { createAuthMiddleware } from "better-auth/api";
const hook = createAuthMiddleware(async (ctx) => {
throw ctx.redirect("/sign-up/name");
});Cookie
- 设置 Cookie:
ctx.setCookies或ctx.setSignedCookie。 - 获取 Cookie:
ctx.getCookies或ctx.getSignedCookies。
示例:
import { createAuthMiddleware } from "better-auth/api";
const hook = createAuthMiddleware(async (ctx) => {
ctx.setCookies("my-cookie", "value");
await ctx.setSignedCookie("my-signed-cookie", "value", ctx.context.secret, {
maxAge: 1000,
});
const cookie = ctx.getCookies("my-cookie");
const signedCookie = await ctx.getSignedCookies("my-signed-cookie");
});错误
使用 APIError 抛出特定状态码和消息的错误:
import { createAuthMiddleware, APIError } from "better-auth/api";
const hook = createAuthMiddleware(async (ctx) => {
throw new APIError("BAD_REQUEST", {
message: "Invalid request",
});
});上下文
ctx 对象内部包含另一个 context 对象,用于保存与认证相关的上下文。包括后置钩子中新创建的会话、Cookie 配置、密码哈希器等。
新会话
端点运行后新创建的会话。此仅在后置钩子中存在。
createAuthMiddleware(async (ctx) => {
const newSession = ctx.context.newSession
});返回值
从钩子返回的值会传递给链中的下一个钩子。
createAuthMiddleware(async (ctx) => {
const returned = ctx.context.returned; //this could be a successful response or an APIError
});响应头部
由端点和在此钩子之前运行的钩子添加的响应头部。
createAuthMiddleware(async (ctx) => {
const responseHeaders = ctx.context.responseHeaders;
});预定义认证 Cookie
访问 BetterAuth 的预定义 Cookie 属性:
createAuthMiddleware(async (ctx) => {
const cookieName = ctx.context.authCookies.sessionToken.name;
});密钥
您可以访问 ctx.context.secret 中的认证实例的 secret。
密码
密码对象提供 hash 和 verify。
ctx.context.password.hash:让您哈希给定的密码。ctx.context.password.verify:让您验证给定的password和hash。
适配器
适配器暴露 Better Auth 使用的适配器方法。包括 findOne、findMany、create、delete、update 和 updateMany。您通常应该使用您的 ORM 中的实际 db 实例,而不是此适配器。
内部适配器
这些是调用您的数据库执行特定操作的调用。createUser、createSession、updateSession...
这可能比直接使用您的数据库更有用,以访问 databaseHooks、适当的 secondaryStorage 支持等。如果您进行类似于此内部适配器操作的查询,值得一看。
generateId
您可以使用 ctx.context.generateId 生成各种原因的 Id。
可重用钩子
如果您需要跨多个端点重用钩子,请考虑创建插件。在 插件文档 中了解更多。