客户端库

Better Auth 提供了一个兼容多种流行前端框架(如 React、Vue、Svelte 等)的客户端库。这个客户端库包含了一组用于与 Better Auth 服务器交互的函数。每个框架的客户端库都是基于一个框架无关的核心客户端库构建的,这确保了所有方法和钩子在所有客户端库中保持一致。

安装

如果你还没有安装,请先安装 better-auth。

npm i better-auth

创建客户端实例

从你使用的框架对应的包中导入 createAuthClient(例如,React 使用 "better-auth/react")。调用该函数来创建你的客户端。传入认证服务器的基础 URL。如果认证服务器与你的客户端在同一域名下运行,你可以跳过这一步。

如果你使用的基础路径不是 /api/auth,请确保传入完整的 URL,包括路径。(例如:http://localhost:3000/custom-path/auth

lib/auth-client.ts
import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient({
    baseURL: "http://localhost:3000" // 认证服务器的基础 URL
})

使用方法

创建客户端实例后,你可以使用该客户端与 Better Auth 服务器进行交互。客户端默认提供了一组函数,并且可以通过插件进行扩展。

示例:登录

auth-client.ts
import { createAuthClient } from "better-auth/client"
const authClient = createAuthClient()
 
await authClient.signIn.email({
    email: "[email protected]",
    password: "password1234"
})

钩子函数

除了普通方法外,客户端还提供了钩子函数来轻松访问不同的响应式数据。每个钩子函数都在客户端的根对象中可用,并且都以 use 开头。

示例:useSession

user.tsx
// 确保你使用的是 React 客户端
import { createAuthClient } from "better-auth/react"
const { useSession } = createAuthClient() 
 
export function User() {
    const {
        data: session,
        isPending, // 加载状态
        error, // 错误对象
        refetch // 重新获取会话
    } = useSession()
    return (
        //...
    )
}

请求选项

客户端使用名为 better fetch 的库来向服务器发送请求。

Better fetch 是原生 fetch API 的封装,提供了更便捷的请求方式。它由 Better Auth 的同一团队开发,专门设计用于无缝配合。

你可以通过在 createAuthClient 中传入 fetchOptions 对象来设置任何默认的请求选项。

auth-client.ts
import { createAuthClient } from "better-auth/client"
 
const authClient = createAuthClient({
    fetchOptions: {
        // 任何 better-fetch 选项
    },
})

你也可以在大多数客户端函数中传入请求选项,可以作为第二个参数或作为对象的属性。

auth-client.ts
await authClient.signIn.email({
    email: "[email protected]",
    password: "password1234",
}, {
    onSuccess(ctx) {
        //      
    }
})
 
// 或者
 
await authClient.signIn.email({
    email: "[email protected]",
    password: "password1234",
    fetchOptions: {
        onSuccess(ctx) {
            //      
        }
    },
})

错误处理

大多数客户端函数都会返回一个包含以下属性的响应对象:

  • data:响应数据
  • error:如果发生错误,则包含错误对象

错误对象包含以下属性:

  • message:错误消息(例如:"邮箱或密码无效")
  • status:HTTP 状态码
  • statusText:HTTP 状态文本
auth-client.ts
const { data, error } = await authClient.signIn.email({
    email: "[email protected]",
    password: "password1234"
})
if (error) {
    // 处理错误
}

如果操作接受 fetchOptions 选项,你可以传入 onError 回调来处理错误。

auth-client.ts
await authClient.signIn.email({
    email: "[email protected]",
    password: "password1234",
}, {
    onError(ctx) {
        // 处理错误
    }
})
 
// 或者
await authClient.signIn.email({
    email: "[email protected]",
    password: "password1234",
    fetchOptions: {
        onError(ctx) {
            // 处理错误
        }
    }
})

useSession 这样的钩子函数在获取会话失败时也会返回一个错误对象。此外,它们还会返回一个 isPending 属性来表示请求是否仍在进行中。

auth-client.ts
const { data, error, isPending } = useSession()
if (error) {
    // 处理错误
}

错误代码

客户端实例包含 $ERROR_CODES 对象,其中包含了服务器返回的所有错误代码。你可以使用它来处理错误翻译或自定义错误消息。

auth-client.ts
const authClient = createAuthClient();
 
type ErrorTypes = Partial<
    Record<
        keyof typeof client.$ERROR_CODES,
        {
            en: string;
            zh: string;
        }
    >
>;
 
const errorCodes = {
    USER_ALREADY_EXISTS: {
        en: "user already registered",
        zh: "用户已注册",
    },
} satisfies ErrorTypes;
 
const getErrorMessage = (code: string, lang: "en" | "zh") => {
    if (code in errorCodes) {
        return errorCodes[code as keyof typeof errorCodes][lang];
    }
    return "";
};
 
const { error } = await authClient.signUp.email({
    email: "[email protected]",
    password: "password",
    name: "User",
});
if(error?.code){
    alert(getErrorMessage(error.code), "zh");
}

插件

你可以通过插件扩展客户端以添加更多功能。插件可以向客户端添加新函数或修改现有函数。

示例:Magic Link 插件

auth-client.ts
import { createAuthClient } from "better-auth/client"
import { magicLinkClient } from "better-auth/client/plugins"
 
const authClient = createAuthClient({
    plugins: [
        magicLinkClient()
    ]
})

添加插件后,你就可以使用插件提供的新函数。

auth-client.ts
await authClient.signIn.magicLink({
    email: "[email protected]"
})

On this page