# 基本用法 (/docs/basic-usage)

开始使用 Better Auth



Better Auth 提供内置的认证支持：

* **邮箱和密码**
* **社交提供商（Google、GitHub、Apple 等）**

同时也可以通过插件轻松扩展，例如：[用户名](/docs/plugins/username)、[魔法链接](/docs/plugins/magic-link)、[通行密钥](/docs/plugins/passkey)、[邮箱验证码](/docs/plugins/email-otp) 等。

## 邮箱 & 密码 [#邮箱--密码]

启用邮箱和密码认证：

```ts title="auth.ts"
import { betterAuth } from "better-auth"

export const auth = betterAuth({
    emailAndPassword: {    // [!code highlight]
        enabled: true // [!code highlight]
    } // [!code highlight]
})
```

### 注册 [#注册]

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

```ts title="sign-up.ts"
import { authClient } from "@/lib/auth-client"; // 导入认证客户端 // [!code highlight]

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`。

```ts title="auth.ts"
import { betterAuth } from "better-auth"

export const auth = betterAuth({
    emailAndPassword: {
    	enabled: true,
    	autoSignIn: false // 默认为 true // [!code highlight]
  },
})
```

### 登录 [#登录]

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

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

<Callout type="warn">
  始终在客户端调用客户端方法。不要从服务器调用它们。
</Callout>

### 服务器端认证 [#服务器端认证]

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

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

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

<Callout>
  如果服务器无法返回响应对象，你需要手动解析并设置 Cookie。但对于 Next.js 等框架，我们提供了[一个插件](/docs/integrations/next#服务器操作中的-cookie)来自动处理
</Callout>

## 社交登录 [#社交登录]

Better Auth 支持多种社交提供商，包括 Google、GitHub、Apple、Discord 等。使用社交提供商时，需在 `auth` 对象的 `socialProviders` 选项中配置相应的提供商。

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

export const auth = betterAuth({
    socialProviders: { // [!code highlight]
        github: { // [!code highlight]
            clientId: process.env.GITHUB_CLIENT_ID!, // [!code highlight]
            clientSecret: process.env.GITHUB_CLIENT_SECRET!, // [!code highlight]
        } // [!code highlight]
    }, // [!code highlight]
})
```

### 使用社交提供商登录 [#使用社交提供商登录]

要使用社交提供商登录，调用 `signIn.social`，并传入如下属性对象：

```ts title="sign-in.ts"
import { authClient } from "@/lib/auth-client"; //导入认证客户端 // [!code highlight]

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,
});
```

你也可以使用社交提供商提供的 `idToken` 或 `accessToken` 进行认证，而无需将用户重定向到提供商的网站。更多详情请参阅社交提供商文档。

## 登出 [#登出]

要登出用户，可以使用客户端提供的 `signOut` 函数。

```ts title="user-card.tsx"
await authClient.signOut();
```

你可以传入 `fetchOptions`，在 onSuccess 时进行重定向

```ts title="user-card.tsx" 
await authClient.signOut({
  fetchOptions: {
    onSuccess: () => {
      router.push("/login"); // 跳转到登录页
    },
  },
});
```

## 会话 [#会话]

用户登录后，你可能需要访问用户会话。Better Auth 支持在服务端和客户端轻松访问会话数据。

### 客户端 [#客户端]

#### 使用会话 [#使用会话]

Better Auth 提供了 `useSession` 钩子，用于客户端轻松访问会话数据。该钩子基于 nanostore 实现，支持所有主流框架和原生客户端，可确保会话状态变化（如登出）立即更新 UI。

<Tabs items="[&#x22;React&#x22;, &#x22;Vue&#x22;,&#x22;Svelte&#x22;, &#x22;Solid&#x22;, &#x22;Vanilla&#x22;]" defaultValue="react">
  <Tab value="React">
    ```tsx title="user.tsx"
    import { authClient } from "@/lib/auth-client" // import the auth client // [!code highlight] 

    export function User(){

        const { // [!code highlight]
            data: session, // [!code highlight]
            isPending, //loading state // [!code highlight]
            error, //error object // [!code highlight]
            refetch //refetch the session
        } = authClient.useSession() // [!code highlight]

        return (
            //...
        )
    }
    ```
  </Tab>

  <Tab value="Vue">
    ```vue title="index.vue"
    <script setup lang="ts">
    import { authClient } from "~/lib/auth-client" // [!code highlight]

    const session = authClient.useSession() // [!code highlight]
    </script>

    <template>
        <div>
            <div>
                <pre>{{ session.data }}</pre>
                <button v-if="session.data" @click="authClient.signOut()">
                    Sign out
                </button>
            </div>
        </div>
    </template>
    ```
  </Tab>

  <Tab value="Svelte">
    ```svelte title="user.svelte"
    <script lang="ts">
    import { authClient } from "$lib/auth-client"; // [!code highlight]

    const session = authClient.useSession(); // [!code highlight]
    </script>
    <p>
        {$session.data?.user.email}
    </p>
    ```
  </Tab>

  <Tab value="Vanilla">
    ```ts title="auth-client.ts"
    import { authClient } from "~/lib/auth-client"; //import the auth client

    authClient.useSession.subscribe((value)=>{
        //do something with the session //
    }) 
    ```
  </Tab>

  <Tab value="Solid">
    ```tsx title="user.tsx"
    import { authClient } from "~/lib/auth-client"; // [!code highlight]

    export default function Home() {
        const session = authClient.useSession() // [!code highlight]
        return (
            <pre>{JSON.stringify(session(), null, 2)}</pre>
        );
    }
    ```
  </Tab>
</Tabs>

#### 获取会话 [#获取会话]

如果不想使用钩子，也可以调用客户端的 `getSession` 方法。

```ts title="user.tsx"
import { authClient } from "@/lib/auth-client" // 导入认证客户端 // [!code highlight]

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

它也可与客户端数据获取库结合使用，比如 [TanStack Query](https://tanstack.com/query/latest)。

### 服务器端 [#服务器端]

服务器端提供了一个 `session` 对象，用于访问会话数据。需要传入请求头对象给 `getSession` 方法。

**示例：使用流行框架**

<Tabs items="[&#x22;Next.js&#x22;, &#x22;Nuxt&#x22;, &#x22;Svelte&#x22;, &#x22;Astro&#x22;, &#x22;Hono&#x22;, &#x22;TanStack&#x22;]">
  <Tab value="Next.js">
    ```ts title="server.ts"
    import { auth } from "./auth"; // 你的 Better Auth 服务器实例路径
    import { headers } from "next/headers";

    const session = await auth.api.getSession({
        headers: await headers() // 需传入请求头对象
    })
    ```
  </Tab>

  <Tab value="react-router">
    ```ts title="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 })
    }
    ```
  </Tab>

  <Tab value="Astro">
    ```astro title="index.astro"
    ---
    import { auth } from "./auth";

    const session = await auth.api.getSession({
        headers: Astro.request.headers,
    });
    ---
    <!-- 你的 Astro 模板 -->
    ```
  </Tab>

  <Tab value="Svelte">
    ```ts title="+page.ts"
    import { auth } from "./auth";

    export async function load({ request }) {
        const session = await auth.api.getSession({
            headers: request.headers
        })
        return {
            props: {
                session
            }
        }
    }
    ```
  </Tab>

  <Tab value="Hono">
    ```ts title="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
        })
    });
    ```
  </Tab>

  <Tab value="Nuxt">
    ```ts title="server/session.ts"
    import { auth } from "~/utils/auth";

    export default defineEventHandler((event) => {
        const session = await auth.api.getSession({
            headers: event.headers,
        })
    });
    ```
  </Tab>

  <Tab value="TanStack">
    ```ts title="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
            })
        },
    });
    ```
  </Tab>
</Tabs>

<Callout>
  更多详情请查看[会话管理](/docs/concepts/session-management)文档
</Callout>

## 使用插件 [#使用插件]

Better Auth 的一大特色是拥有插件生态系统，能够通过少量代码实现复杂的认证功能。

下面示例演示如何使用两步验证插件添加双因素认证。

<Steps>
  <Step>
    ### 服务器配置 [#服务器配置]

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

    ```ts title="auth.ts"
    import { betterAuth } from "better-auth"
    import { twoFactor } from "better-auth/plugins" // [!code highlight]

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

    现在，服务器上将提供与双因素相关的路由和方法
  </Step>

  <Step>
    ### 迁移数据库 [#迁移数据库]

    添加插件后，需要将所需的表添加到数据库中。你可以运行 `migrate` 命令，或者使用 `generate` 命令创建架构并手动处理迁移。

    生成架构：

    ```bash title="terminal"
    npx auth generate
    ```

    使用 `migrate` 命令：

    ```bash title="terminal"
    npx auth migrate
    ```

    <Callout>
      如果你更喜欢手动添加架构，可以查看[双因素插件](/docs/plugins/2fa#模式-schema)文档中所需的架构
    </Callout>
  </Step>

  <Step>
    ### 客户端配置 [#客户端配置]

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

    ```ts title="auth-client.ts"  
    import { createAuthClient } from "better-auth/client";
    import { twoFactorClient } from "better-auth/client/plugins"; // [!code highlight]

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

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

    ```ts title="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
        })
    }
    ```
  </Step>

  <Step>
    下一步：查看 <Link href="/docs/plugins/2fa">双因素插件文档</Link>
  </Step>
</Steps>

