插件
插件是Better Auth的关键组成部分,它们让你可以扩展基础功能。你可以使用它们来添加新的认证方法、功能或自定义行为。
Better Auth提供了许多内置插件供你使用。查看插件部分了解详情。你也可以创建自己的插件。
使用插件
插件可以是服务器端插件、客户端插件,或两者兼有。
要在服务器端添加插件,将其包含在认证配置的 plugins
数组中。插件将使用提供的选项进行初始化。
客户端插件在创建客户端时添加。大多数插件需要服务器和客户端插件才能正常工作。
前端的 Better Auth 认证客户端使用 better-auth/client
提供的 createAuthClient
函数。
我们建议将 auth-client 和你的普通 auth 实例保存在不同的文件中。
创建插件
首先,你需要一个服务器插件。 服务器插件是所有插件的核心,而客户端插件则提供与前端 API 的接口,以便轻松使用你的服务器插件。
如果你的服务器插件有需要从客户端调用的端点,你还需要创建一个客户端插件。
插件可以做什么?
- 创建自定义
endpoint
来执行任何你想要的操作。 - 使用自定义
schemas
扩展数据库表。 - 使用
middleware
通过其路由匹配器定位一组路由,并仅在通过请求调用这些路由时运行。 - 使用
hooks
定位特定路由或请求。如果你想在端点被直接调用时也运行钩子。 - 使用
onRequest
或onResponse
如果你想做一些影响所有请求或响应的事情。 - 创建自定义
rate-limit
规则。
创建服务器插件
要创建服务器插件,你需要传递一个满足 BetterAuthPlugin
接口的对象。
唯一必需的属性是 id
,它是插件的唯一标识符。
服务器和客户端插件可以使用相同的 id
。
你不必让插件成为一个函数,但建议这样做。这样你可以向插件传递选项,并且与内置插件保持一致。
端点
要向服务器添加端点,你可以传递 endpoints
,它需要一个对象,其中键是任何 string
,值是 AuthEndpoint
。
要创建 Auth 端点,你需要从 better-auth
导入 createAuthEndpoint
。
Better Auth 使用另一个名为 Better Call 的库来创建端点。Better Call 是由 Better Auth 背后的同一团队开发的简单 ts web 框架。
Create Auth 端点包装了 Better Call 的 createEndpoint
。在 ctx
对象内部,它会提供另一个名为 context
的对象,让你可以访问 better-auth 特定的上下文,包括 options
、db
、baseURL
等。
上下文对象
appName
: 应用程序的名称。默认为 "Better Auth"。options
: 传递给 Better Auth 实例的选项。tables
: 核心表定义。它是一个对象,其中键是表名,值是模式定义。baseURL
: 认证服务器的基础 URL。这包括路径。例如,如果服务器运行在http://localhost:3000
,默认情况下 baseURL 将是http://localhost:3000/api/auth
,除非用户更改。session
: 会话配置。包括updateAge
和expiresIn
值。secret
: 用于各种目的的密钥。这由用户定义。authCookie
: 核心认证 cookie 的默认 cookie 配置。logger
: Better Auth 使用的日志记录器实例。db
: Better Auth 用于与数据库交互的 Kysely 实例。adapter
: 这与 db 相同,但它为你提供类似orm
的函数来与数据库交互。(除非你需要原始 SQL 查询或出于性能原因,否则我们建议使用这个而不是db
)internalAdapter
: 这些是 Better Auth 使用的内部数据库调用。例如,你可以使用这些调用来创建会话,而不是直接使用adapter
。internalAdapter.createSession(userId)
createAuthCookie
: 这是一个辅助函数,让你可以获取 cookie 的name
和options
,用于set
或get
cookie。它根据 cookie 实现__secure
前缀和__host
前缀等功能。
对于其他属性,你可以查看 Better Call 文档和 源代码。
端点规则
- 确保在端点路径中使用 kebab-case
- 确保端点只使用
POST
或GET
方法 - 任何修改数据的函数应该是
POST
方法 - 任何获取数据的函数应该是
GET
方法 - 确保使用
createAuthEndpoint
函数创建 API 端点 - 确保你的路径是唯一的,以避免与其他插件冲突。如果你使用通用路径,请在路径前添加插件名称。(使用
/my-plugin/hello-world
而不是/hello-world
)
模式
你可以通过传递 schema
对象来为插件定义数据库模式。模式对象应该以表名为键,以模式定义为值。
字段
默认情况下,better-auth 会为每个表创建一个 id
字段。你可以通过将它们添加到 fields
对象来向表添加其他字段。
键是列名,值是列定义。列定义可以具有以下属性:
type
: 字段的类型。可以是 string
、number
、boolean
、date
。
required
: 如果字段在新记录中应该是必需的。(默认:false
)
unique
: 如果字段应该是唯一的。(默认:false
)
reference
: 如果字段是对另一个表的引用。(默认:null
)它接受一个具有以下属性的对象:
model
: 要引用的表名。field
: 要引用的字段名。onDelete
: 删除引用的记录时要采取的操作。(默认:null
)
其他模式属性
disableMigration
: 如果表不应该被迁移。(默认:false
)
如果你向 user
或 session
表添加其他字段,类型将在 getSession
和 signUpEmail
调用中自动推断。
这将向 user
表添加一个 age
字段,所有返回 user
的端点都将包含 age
字段,并且它将被 TypeScript 正确推断。
不要在 user
或 session
表中存储敏感信息。如果你需要存储敏感信息,请创建一个新表。
钩子
钩子用于在从客户端或直接在服务器上执行操作之前或之后运行代码。你可以通过传递 hooks
对象向服务器添加钩子,该对象应包含 before
和 after
属性。
中间件
你可以通过传递 middlewares
数组向服务器添加中间件。这个数组应该包含中间件对象,每个对象都有一个 path
和一个 middleware
属性。与钩子不同,中间件只在来自客户端的 api
请求上运行。如果端点被直接调用,中间件将不会运行。
path
可以是字符串或路径匹配器,使用与 better-call
相同的路径匹配系统。
如果你从中间件抛出 APIError
或返回 Response
对象,请求将被停止,响应将被发送到客户端。
请求前和响应后
除了中间件,你还可以在请求发出之前和响应返回之后进行钩入。这主要用于如果你想做一些影响所有请求或响应的事情。
请求前
onRequest
函数在请求发出之前被调用。它接受两个参数:request
和 context
对象。
它的工作方式如下:
- 正常继续:如果你不返回任何内容,请求将照常进行。
- 中断请求:要停止请求并发送响应,返回一个包含
response
属性的对象,该属性包含Response
对象。 - 修改请求:你也可以返回修改后的
request
对象来在发送前更改请求。
响应后
onResponse
函数在响应返回后立即执行。它接受两个参数:response
和 context
对象。
使用方法如下:
- 修改响应:你可以返回修改后的响应对象来在发送到客户端之前更改响应。
- 正常继续:如果你不返回任何内容,响应将按原样发送。
速率限制
你可以通过传递 rateLimit
数组为插件定义自定义速率限制规则。速率限制数组应包含速率限制对象数组。
服务器插件辅助函数
一些用于创建服务器插件的额外辅助函数。
getSessionFromCtx
允许你通过传递认证中间件的 context
来获取客户端的会话数据。
sessionMiddleware
一个检查客户端是否有有效会话的中间件。如果客户端有有效会话,它会将会话数据添加到上下文对象中。
创建客户端插件
如果你的端点需要从客户端调用,你还需要创建一个客户端插件。Better Auth 客户端可以从服务器插件推断端点。你也可以添加额外的客户端逻辑。
端点接口
通过向客户端插件添加 $InferServerPlugin
键,从服务器插件推断端点。
客户端将 path
推断为对象,并将 kebab-case 转换为 camelCase。例如,/my-plugin/hello-world
变为 myPlugin.helloWorld
。
获取操作
如果你需要向客户端添加额外的方法或其他内容,你可以使用 getActions
函数。这个函数使用客户端的 fetch
函数调用。
Better Auth 使用 Better fetch 来发出请求。Better fetch 是由 Better Auth 的作者开发的简单 fetch 包装器。
作为一般准则,确保每个函数只接受一个参数,第二个可选参数用于 fetchOptions,允许用户向 fetch 调用传递额外的选项。函数应该返回一个包含 data 和 error 键的对象。
如果你的用例涉及 API 调用之外的操作,可以自由地偏离这个规则。
获取原子
这只有在你想提供类似 useSession
的 hooks
时才有用。
Get atoms 使用 better fetch 的 fetch
函数调用,它应该返回一个包含原子的对象。原子应该使用 nanostores 创建。原子将由 nanostores 提供的每个框架的 useStore
hook 解析。
查看内置插件以了解如何正确使用原子的示例。
路径方法
默认情况下,推断的路径在不需要主体时使用 GET
方法,在需要主体时使用 POST
方法。你可以通过传递 pathMethods
对象来覆盖这一点。键应该是路径,值应该是方法("POST" | "GET")。
Fetch 插件
如果你需要使用 better fetch 插件,你可以将它们传递给 fetchPlugins
数组。你可以在 better fetch 文档 中阅读更多关于 better fetch 插件的信息。
原子监听器
这只有在你想提供类似 useSession
的 hooks
并且你想监听原子并在它们改变时重新评估它们时才有用。
你可以查看内置插件中如何使用这个。