基本用法

Better Auth 提供内置的身份验证支持,包括:

  • 邮箱和密码
  • 社交登录提供商(Google、GitHub、Apple 等)

同时也可以通过插件轻松扩展,例如:用户名魔法链接通行密钥邮箱一次性密码等。

邮箱与密码

要启用邮箱和密码身份验证:

auth.ts
import { betterAuth } from "better-auth"

export const auth = betterAuth({
    emailAndPassword: {    
        enabled: true
    } 
})

注册

要注册用户,你需要调用客户端方法 signUp.email 并传入用户信息。

sign-up.ts
import { authClient } from "@/lib/auth-client"; // 导入 auth 客户端

const { data, error } = await authClient.signUp.email({
        email, // 用户邮箱地址
        password, // 用户密码 -> 默认至少 8 个字符
        name, // 用户显示名称
        image, // 用户头像 URL(可选)
        callbackURL: "/dashboard" // 用户验证邮箱后重定向的 URL(可选)
    }, {
        onRequest: (ctx) => {
            // 显示加载状态
        },
        onSuccess: (ctx) => {
            // 重定向到仪表板或登录页面
        },
        onError: (ctx) => {
            // 显示错误信息
            alert(ctx.error.message);
        },
});

默认情况下,用户成功注册后会自动登录。要禁用此行为,可以将 autoSignIn 设置为 false

auth.ts
import { betterAuth } from "better-auth"

export const auth = betterAuth({
    emailAndPassword: {
    	enabled: true,
    	autoSignIn: false // 默认为 true
  },
})

用户登录

要登录用户,可以使用客户端提供的 signIn.email 函数。

sign-in
const { data, error } = await authClient.signIn.email({
        /**
         * 用户邮箱
         */
        email,
        /**
         * 用户密码
         */
        password,
        /**
         * 用户验证邮箱后重定向的 URL(可选)
         */
        callbackURL: "/dashboard",
        /**
         * 浏览器关闭后是否记住用户会话
         * @default true
         */
        rememberMe: false
}, {
    // 回调函数
})

始终在客户端调用客户端方法。不要在服务器端调用。

服务端认证

要在服务器端认证用户,可以使用 auth.api 方法。

server.ts
import { auth } from "./auth"; // 指向你的 Better Auth 服务器实例的路径

const response = await auth.api.signInEmail({
    body: {
        email,
        password
    },
    asResponse: true // 返回响应对象而不是数据
});

如果服务器无法返回响应对象,你需要手动解析和设置 cookies。但对于 Next.js 等框架,我们提供了插件来自动处理此问题

社交登录

Better Auth 支持多种社交登录提供商,包括 Google、GitHub、Apple、Discord 等。要使用社交提供商,您需要在 auth 对象的 socialProviders 选项中配置所需的提供商。

auth.ts
import { betterAuth } from "better-auth";

export const auth = betterAuth({
    socialProviders: { 
        github: { 
            clientId: process.env.GITHUB_CLIENT_ID!, 
            clientSecret: process.env.GITHUB_CLIENT_SECRET!, 
        } 
    }, 
})

使用社交提供商登录

要使用社交提供商登录,您需要调用 signIn.social。它接受一个包含以下属性的对象:

sign-in.ts
import { authClient } from "@/lib/auth-client"; // 导入 auth 客户端

await authClient.signIn.social({
    /**
     * 社交提供商 ID
     * @example "github", "google", "apple"
     */
    provider: "github",
    /**
     * 用户在提供商处认证后重定向的 URL
     * @default "/"
     */
    callbackURL: "/dashboard", 
    /**
     * 登录过程中发生错误时重定向的 URL
     */
    errorCallbackURL: "/error",
    /**
     * 用户是新注册时重定向的 URL
     */
    newUserCallbackURL: "/welcome",
    /**
     * 禁用自动重定向到提供商。
     * @default false
     */
    disableRedirect: true,
});

您也可以使用来自社交提供商的 idTokenaccessToken 进行认证,而不是将用户重定向到提供商的网站。有关更多详细信息,请参阅社交提供商文档。

退出登录

要退出用户登录,你可以使用客户端提供的 signOut 函数。

user-card.tsx
await authClient.signOut();

你可以传递 fetchOptions 来在成功后重定向

user-card.tsx
await authClient.signOut({
  fetchOptions: {
    onSuccess: () => {
      router.push("/login"); // 重定向到登录页面
    },
  },
});

会话

一旦用户登录,你可能需要访问用户会话。Better Auth 允许你轻松地从服务器端和客户端访问会话数据。

客户端

使用会话

Better Auth 提供了一个 useSession hook,用于在客户端轻松访问会话数据。该 hook 使用 nanostore 实现,并支持每种受支持的框架和原生客户端,确保对会话的任何更改(例如登出)都会立即反映在您的 UI 中。

user.tsx
import { authClient } from "@/lib/auth-client" // 导入 auth 客户端

export function User(){

    const { 
        data: session, 
        isPending, //加载状态
        error, //错误对象
        refetch //重新获取会话
    } = authClient.useSession() 

    return (
        //...
    )
}
index.vue
<script setup lang="ts">
import { authClient } from "~/lib/auth-client"

const session = authClient.useSession() 
</script>

<template>
    <div>
        <div>
            <pre>{{ session.data }}</pre>
            <button v-if="session.data" @click="authClient.signOut()">
                登出
            </button>
        </div>
    </div>
</template>
user.svelte
<script lang="ts">
import { authClient } from "$lib/auth-client"; 

const session = authClient.useSession(); 
</script>
<p>
    {$session.data?.user.email}
</p>
user.svelte
import { authClient } from "~/lib/auth-client"; //导入 auth 客户端

authClient.useSession.subscribe((value)=>{
    //使用会话执行某些操作 //
}) 
user.tsx
import { authClient } from "~/lib/auth-client"; 

export default function Home() {
    const session = authClient.useSession() 
    return (
        <pre>{JSON.stringify(session(), null, 2)}</pre>
    );
}

获取会话

如果您不想使用钩子函数,可以使用客户端提供的 getSession 方法。

user.tsx
import { authClient } from "@/lib/auth-client" // 导入身份验证客户端

const { data: session, error } = await authClient.getSession()

您也可以将其与客户端数据获取库(如 TanStack Query)一起使用。

服务端

服务端提供了一个 session 对象,您可以使用它来访问会话数据。这需要将请求头对象传递给 getSession 方法。

示例:使用一些流行框架

server.ts
import { auth } from "./auth"; // 指向你的 Better Auth 服务器实例的路径
import { headers } from "next/headers";

const session = await auth.api.getSession({
    headers: await headers() // 你需要传递 headers 对象
})
route.ts
import { auth } from "lib/auth"; // 指向你的 Better Auth 服务器实例的路径

export async function loader({ request }: LoaderFunctionArgs) {
    const session = await auth.api.getSession({
        headers: request.headers
    })

    return json({ session })
}
index.astro
---
import { auth } from "./auth";

const session = await auth.api.getSession({
    headers: Astro.request.headers,
});
---
<!-- 你的 Astro 模板 -->
+page.ts
import { auth } from "./auth";

export async function load({ request }) {
    const session = await auth.api.getSession({
        headers: request.headers
    })
    return {
        props: {
            session
        }
    }
}
index.ts
import { auth } from "./auth";

const app = new Hono();

app.get("/path", async (c) => {
    const session = await auth.api.getSession({
        headers: c.req.raw.headers
    })
});
server/session.ts
import { auth } from "~/utils/auth";

export default defineEventHandler((event) => {
    const session = await auth.api.getSession({
        headers: event.headers,
    })
});
app/routes/api/index.ts
import { auth } from "./auth";
import { createAPIFileRoute } from "@tanstack/start/api";

export const APIRoute = createAPIFileRoute("/api/$")({
    GET: async ({ request }) => {
        const session = await auth.api.getSession({
            headers: request.headers
        })
    },
});

更多详细信息请查看会话管理文档。

使用插件

Better Auth 的一个独特功能是其插件生态系统。它允许您通过少量代码添加复杂的身份验证相关功能。

以下是一个使用双因素认证插件添加双因素认证的示例。

服务器配置

要添加插件,您需要导入插件并将其传递给 auth 实例的 plugins 选项。例如,要添加双因素认证,您可以使用以下代码:

auth.ts
import { betterAuth } from "better-auth"
import { twoFactor } from "better-auth/plugins"

export const auth = betterAuth({
    //...其他选项
    plugins: [ 
        twoFactor() 
    ] 
})

现在,与双因素认证相关的路由和方法将在服务器上可用。

数据库迁移

添加插件后,您需要将所需的表添加到数据库中。您可以通过运行 migrate 命令来完成此操作,或者使用 generate 命令创建模式并手动处理迁移。

生成模式:

terminal
npx @better-auth/cli generate

使用 migrate 命令:

terminal
npx @better-auth/cli migrate

如果您更喜欢手动添加模式,可以在双因素认证插件文档中查看所需的模式。

客户端配置

完成服务器端配置后,我们需要将插件添加到客户端。为此,您需要导入插件并将其传递给 auth 客户端的 plugins 选项。例如,要添加双因素认证,您可以使用以下代码:

auth-client.ts
import { createAuthClient } from "better-auth/client";
import { twoFactorClient } from "better-auth/client/plugins"; 

const authClient = createAuthClient({
    plugins: [ 
        twoFactorClient({ 
            twoFactorPage: "/two-factor" // 如果用户需要验证第二因素时重定向的页面
        }) 
    ] 
})

现在,与双因素相关的方法将在客户端可用。

profile.ts
import { authClient } from "./auth-client"

const enableTwoFactor = async() => {
    const data = await authClient.twoFactor.enable({
        password // 需要用户密码
    }) // 这将启用双因素认证
}

const disableTwoFactor = async() => {
    const data = await authClient.twoFactor.disable({
        password // 需要用户密码
    }) // 这将禁用双因素认证
}

const signInWith2Factor = async() => {
    const data = await authClient.signIn.email({
        //...
    })
    // 如果用户启用了双因素认证,将会重定向到双因素认证页面
}

const verifyTOTP = async() => {
    const data = await authClient.twoFactor.verifyTOTP({
        code: "123456", // 用户输入的验证码
        /**
         * 如果设备是受信任的,用户在同一设备上
         * 将不需要再次通过双因素认证
         */
        trustDevice: true
    })
}

下一步:查看双因素插件文档

On this page