基本用法

Better Auth 提供内置的身份验证支持,用于:

【Better Auth provides built-in authentication support for:】

  • 电子邮件和密码
  • 社交提供商(Google、GitHub、Apple 等)

但也可以通过插件轻松扩展,例如:usernamemagic linkpasskeyemail-otp 等。

【But also can easily be extended using plugins, such as: username, magic link, passkey, email-otp, and more.】

电子邮箱和密码

【Email & Password】

要启用电子邮件和密码认证:

【To enable email and password authentication:】

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

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

注册

【Sign Up】

要注册用户,你需要使用用户的信息调用客户端方法 signUp.email

【To sign up a user you need to call the client method signUp.email with the user's information.】

sign-up.ts
import { authClient } from "@/lib/auth-client"; //import the auth client

const { data, error } = await authClient.signUp.email({
        email, // user email address
        password, // user password -> min 8 characters by default
        name, // user display name
        image, // User image URL (optional)
        callbackURL: "/dashboard" // A URL to redirect to after the user verifies their email (optional)
    }, {
        onRequest: (ctx) => {
            //show loading
        },
        onSuccess: (ctx) => {
            //redirect to the dashboard or sign in page
        },
        onError: (ctx) => {
            // display the error message
            alert(ctx.error.message);
        },
});

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

【By default, the users are automatically signed in after they successfully sign up. To disable this behavior you can set autoSignIn to false.】

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

export const auth = betterAuth({
    emailAndPassword: {
    	enabled: true,
    	autoSignIn: false //defaults to true
  },
})

登录

【Sign In】

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

【To sign a user in, you can use the signIn.email function provided by the client.】

sign-in
const { data, error } = await authClient.signIn.email({
        /**
         * The user email
         */
        email,
        /**
         * The user password
         */
        password,
        /**
         * A URL to redirect to after the user verifies their email (optional)
         */
        callbackURL: "/dashboard",
        /**
         * remember the user session after the browser is closed. 
         * @default true
         */
        rememberMe: false
}, {
    //callbacks
})

始终从客户端调用客户端方法。不要从服务器端调用它们。

服务器端认证

【Server-Side Authentication】

要在服务器上验证用户身份,你可以使用 auth.api 方法。

【To authenticate a user on the server, you can use the auth.api methods.】

server.ts
import { auth } from "./auth"; // path to your Better Auth server instance

const response = await auth.api.signInEmail({
    body: {
        email,
        password
    },
    asResponse: true // returns a response object instead of data
});

如果服务器无法返回响应对象,你需要手动解析并设置 cookie。但对于像 Next.js 这样的框架,我们提供了 一个插件 来自动处理此操作

社交登录

【Social Sign-On】

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

【Better Auth supports multiple social providers, including Google, GitHub, Apple, Discord, and more. To use a social provider, you need to configure the ones you need in the socialProviders option on your auth object.】

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!, 
        } 
    }, 
})

使用社交账号登录

【Sign in with social providers】

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

【To sign in using a social provider you need to call signIn.social. It takes an object with the following properties:】

sign-in.ts
import { authClient } from "@/lib/auth-client"; //import the auth client

await authClient.signIn.social({
    /**
     * The social provider ID
     * @example "github", "google", "apple"
     */
    provider: "github",
    /**
     * A URL to redirect after the user authenticates with the provider
     * @default "/"
     */
    callbackURL: "/dashboard", 
    /**
     * A URL to redirect if an error occurs during the sign in process
     */
    errorCallbackURL: "/error",
    /**
     * A URL to redirect if the user is newly registered
     */
    newUserCallbackURL: "/welcome",
    /**
     * disable the automatic redirect to the provider. 
     * @default false
     */
    disableRedirect: true,
});

你也可以使用来自社交提供商的 idTokenaccessToken 进行身份验证,而无需将用户重定向到提供商的网站。更多详情请参阅社交提供商的文档。

【You can also authenticate using idToken or accessToken from the social provider instead of redirecting the user to the provider's site. See social providers documentation for more details. 】

登出

【Signout】

要注销用户,你可以使用客户端提供的 signOut 函数。

【To signout a user, you can use the signOut function provided by the client.】

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

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

【you can pass fetchOptions to redirect onSuccess】

user-card.tsx
await authClient.signOut({
  fetchOptions: {
    onSuccess: () => {
      router.push("/login"); // redirect to login page
    },
  },
});

会话

【Session】

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

【Once a user is signed in, you'll want to access the user session. Better Auth allows you to easily access the session data from both the server and client sides.】

客户端

【Client Side】

使用会话

【Use Session】

Better Auth 提供了一个 useSession 钩子,方便在客户端访问会话数据。该钩子使用 nanostore 实现,并支持所有受支持的框架和原生客户端,确保会话的任何变化(例如登出)都会立即在你的界面上反映出来。

【Better Auth provides a useSession hook to easily access session data on the client side. This hook is implemented using nanostore and has support for each supported framework and vanilla client, ensuring that any changes to the session (such as signing out) are immediately reflected in your UI.】

user.tsx
import { authClient } from "@/lib/auth-client" // import the auth client

export function User(){

    const { 
        data: session, 
        isPending, //loading state
        error, //error object
        refetch //refetch the session
    } = 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()">
                Sign out
            </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>
auth-client.ts
import { authClient } from "~/lib/auth-client"; //import the auth client

authClient.useSession.subscribe((value)=>{
    //do something with the session //
}) 
user.tsx
import { authClient } from "~/lib/auth-client"; 

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

获取会话

【Get Session】

如果你不想使用 hook,可以使用客户端提供的 getSession 方法。

【If you prefer not to use the hook, you can use the getSession method provided by the client.】

user.tsx
import { authClient } from "@/lib/auth-client" // import the auth client

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

你也可以将它与客户端数据获取库一起使用,比如 TanStack Query

【You can also use it with client-side data-fetching libraries like TanStack Query.】

服务器端

【Server Side】

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

【The server provides a session object that you can use to access the session data. It requires request headers object to be passed to the getSession method.】

示例:使用一些流行的框架

server.ts
import { auth } from "./auth"; // path to your Better Auth server instance
import { headers } from "next/headers";

const session = await auth.api.getSession({
    headers: await headers() // you need to pass the headers object.
})
route.ts
import { auth } from "lib/auth"; // path to your Better Auth server instance

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,
});
---
<!-- Your Astro Template -->
+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
        })
    },
});

更多详情请查看 会话管理 文档。

使用插件

【Using Plugins】

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

【One of the unique features of Better Auth is a plugins ecosystem. It allows you to add complex auth related functionality with small lines of code.】

下面是如何使用双因素插件添加双因素认证的示例。

【Below is an example of how to add two factor authentication using two factor plugin.】

服务器配置

【Server Configuration】

要添加插件,你需要导入插件并将其传递给身份验证实例的 plugins 选项。例如,要添加两步验证,你可以使用以下代码:

【To add a plugin, you need to import the plugin and pass it to the plugins option of the auth instance. For example, to add two factor authentication, you can use the following code:】

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

export const auth = betterAuth({
    //...rest of the options
    plugins: [ 
        twoFactor() 
    ] 
})

now two factor related routes and method will be available on the server.

迁移数据库

【Migrate Database】

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

【After adding the plugin, you'll need to add the required tables to your database. You can do this by running the migrate command, or by using the generate command to create the schema and handle the migration manually.】

生成模式:

【generating the schema:】

terminal
npx @better-auth/cli generate

使用 migrate 命令:

【using the migrate command:】

terminal
npx @better-auth/cli migrate

如果你更喜欢手动添加架构,可以在 双重验证插件 文档中查看所需的架构。

客户端配置

【Client Configuration】

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

【Once we're done with the server, we need to add the plugin to the client. To do this, you need to import the plugin and pass it to the plugins option of the auth client. For example, to add two factor authentication, you can use the following code:】

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

const authClient = createAuthClient({
    plugins: [ 
        twoFactorClient({ 
            twoFactorPage: "/two-factor" // the page to redirect if a user needs to verify 2nd factor
        }) 
    ] 
})

现在客户端将提供两种与双因素相关的方法。

【now two factor related methods will be available on the client.】

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

const enableTwoFactor = async() => {
    const data = await authClient.twoFactor.enable({
        password // the user password is required
    }) // this will enable two factor
}

const disableTwoFactor = async() => {
    const data = await authClient.twoFactor.disable({
        password // the user password is required
    }) // this will disable two factor
}

const signInWith2Factor = async() => {
    const data = await authClient.signIn.email({
        //...
    })
    //if the user has two factor enabled, it will redirect to the two factor page
}

const verifyTOTP = async() => {
    const data = await authClient.twoFactor.verifyTOTP({
        code: "123456", // the code entered by the user 
        /**
         * If the device is trusted, the user won't
         * need to pass 2FA again on the same device
         */
        trustDevice: true
    })
}

下一步:查看 双重验证插件文档

On this page