安装

学习如何在你的项目中配置 Better Auth。

安装包

让我们先将 Better Auth 添加到你的项目中:

npm install better-auth

如果你使用的是分开的客户端和服务器架构,确保在项目的客户端和服务器部分都安装 Better Auth。

设置环境变量

在项目根目录创建一个 .env 文件,并添加以下环境变量:

  1. 密钥

用于加密和哈希的密钥值。必须至少 32 个字符且需要高熵生成。点击下方按钮生成一个。你也可以用 openssl rand -base64 32 来生成。

.env
BETTER_AUTH_SECRET=

以后需要更换密钥?你可以使用复数形式的 BETTER_AUTH_SECRETS 来平滑切换新密钥,而不使现有数据失效。详情见 secrets 选项

  1. 设置基础 URL
.env
BETTER_AUTH_URL=http://localhost:3000 # 你的应用基础 URL

创建 Better Auth 实例

在以下位置之一创建一个名为 auth.ts 的文件:

  • 项目根目录
  • lib/ 文件夹
  • utils/ 文件夹

你也可以将这些文件夹放在 src/app/server/ 文件夹下(例如 src/lib/auth.tsapp/lib/auth.ts)。

在该文件中,导入 Better Auth 并创建你的 auth 实例。确保导出的实例变量名为 auth 或作为默认导出。

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

export const auth = betterAuth({
  //...
});

配置数据库

Better Auth 需要数据库来存储用户数据。 你可以轻松配置 Better Auth 使用 SQLite、PostgreSQL、MySQL 等!

如果不配置数据库,也可以让 Better Auth 运行在无状态模式,详见无状态会话管理。注意,大多数插件需要数据库支持。

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

export const auth = betterAuth({
    database: new Database("./sqlite.db"),
})
auth.ts
import { betterAuth } from "better-auth";
import { Pool } from "pg";

export const auth = betterAuth({
    database: new Pool({
        // 连接选项
    }),
})
auth.ts
import { betterAuth } from "better-auth";
import { createPool } from "mysql2/promise";

export const auth = betterAuth({
    database: createPool({
        // 连接选项
    }),
})

或者,如果你更喜欢使用 ORM,可以使用内置的适配器之一。

auth.ts
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/db"; // 你的 drizzle 实例

export const auth = betterAuth({
    database: drizzleAdapter(db, {
        provider: "pg", // 或 "mysql"、"sqlite"
    }),
});
auth.ts
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
// 如果你的 Prisma 文件路径不同,可以调整导入路径
import { PrismaClient } from "@/generated/prisma/client";

const prisma = new PrismaClient();
export const auth = betterAuth({
    database: prismaAdapter(prisma, {
        provider: "sqlite", // 或 "mysql"、"postgresql" 等
    }),
});
auth.ts
import { betterAuth } from "better-auth";
import { mongodbAdapter } from "better-auth/adapters/mongodb";
import { client } from "@/db"; // 你的 mongodb 客户端

export const auth = betterAuth({
    database: mongodbAdapter(client),
});

如果你的数据库不在上述列表中,请查看我们支持的其他 数据库 获取更多信息, 或使用支持的 ORM。

创建数据库表

Better Auth 包含一个 CLI 工具,帮助管理库所需的数据库模式。

  • 生成:该命令生成 ORM 模式或 SQL 迁移文件。

如果你使用的是 Kysely,可以直接使用下面的 migrate 命令应用迁移。只有计划手动应用迁移时,才用 generate 命令。

npx auth@latest generate
  • 迁移:该命令直接在数据库中创建所需表。(仅支持内置的 Kysely 适配器)

    npx auth@latest migrate

查看 CLI 文档 获取更多信息。

如果你想手动创建模式,可以在数据库部分找到核心模式。

认证方式

配置你想使用的认证方式。Better Auth 内置支持邮箱密码和社交登录提供商。

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

export const auth = betterAuth({
  //...其他配置
  emailAndPassword: { 
    enabled: true, 
  }, 
  socialProviders: { 
    github: { 
      clientId: process.env.GITHUB_CLIENT_ID as string, 
      clientSecret: process.env.GITHUB_CLIENT_SECRET as string, 
    }, 
  }, 
});

你还可以通过插件使用更多认证方式,如 passkey, 用户名, 神奇链接 等。

挂载处理器

为了处理 API 请求,需要在服务器上设置路由处理器。

在你的框架指定的全匹配路由处理文件中创建一个新文件或路由,该路由应负责处理 /api/auth/* 路径的请求(除非你配置了其他基础路径)。

Better Auth 支持任何带有标准 Request 和 Response 对象的后端框架,并为流行框架提供帮助函数。

/app/api/auth/[...all]/route.ts
import { auth } from "@/lib/auth"; // 你的 auth 文件路径
import { toNextJsHandler } from "better-auth/next-js";

export const { POST, GET } = toNextJsHandler(auth);
/pages/api/auth/[...all].ts
import { auth } from "@/lib/auth"; // 你的 auth 文件路径
import { toNodeHandler } from "better-auth/node";

// 不允许自动解析请求体,手动解析
export const config = { api: { bodyParser: false } };
export default toNodeHandler(auth.handler);
/server/api/auth/[...all].ts
import { auth } from "~/utils/auth"; // 你的 auth 文件路径

export default defineEventHandler((event) => {
    return auth.handler(toWebRequest(event));
});
hooks.server.ts
import { auth } from "$lib/auth"; // 你的 auth 文件路径
import { svelteKitHandler } from "better-auth/svelte-kit";
import { building } from '$app/environment'

export async function handle({ event, resolve }) {
    return svelteKitHandler({ event, resolve, auth, building });
}
/app/routes/api.auth.$.ts
import { auth } from '~/lib/auth.server' // 根据情况调整路径
import type { LoaderFunctionArgs, ActionFunctionArgs } from "react-router" // 或 "@remix-run/node"

export async function loader({ request }: LoaderFunctionArgs) {
    return auth.handler(request)
}

export async function action({ request }: ActionFunctionArgs) {
    return auth.handler(request)
}
/routes/api/auth/*all.ts
import { auth } from "~/lib/auth"; // 你的 auth 文件路径
import { toSolidStartHandler } from "better-auth/solid-start";

export const { GET, POST } = toSolidStartHandler(auth);
src/index.ts
import { Hono } from "hono";
import { auth } from "./auth"; // 你的 auth 文件路径
import { serve } from "@hono/node-server";
import { cors } from "hono/cors";

const app = new Hono();

app.on(["POST", "GET"], "/api/auth/*", (c) => auth.handler(c.req.raw));

serve(app);
src/index.ts
import { auth } from "./auth"; // 你的 auth 文件路径

export default {
    async fetch(request: Request) {
        const url = new URL(request.url);

        // 处理 auth 路由
        if (url.pathname.startsWith("/api/auth")) {
            return auth.handler(request);
        }

        // 处理其他路由
        return new Response("Not found", { status: 404 });
    },
};

Node.js AsyncLocalStorage 支持:Better Auth 使用 AsyncLocalStorage 跟踪异步上下文。要在 Cloudflare Workers 启用此功能,请在 wrangler.toml 中添加 nodejs_compat 标志:

wrangler.toml
compatibility_flags = ["nodejs_compat"]
compatibility_date = "2024-09-23"

如果只需要 AsyncLocalStorage 支持:

wrangler.toml
compatibility_flags = ["nodejs_als"]

下一个重大版本中,我们默认假设支持 AsyncLocalStorage,因此需要此配置。

ExpressJS v5 对路由路径匹配做了破坏性更改,改用 path-to-regexp@6。通配符路由 * 应改成命名语法,比如 /{*any},以正确捕获全匹配模式。详见Express v5 迁移指南

因此,ExpressJS v5 中应如下实现:

app.all('/api/auth/{*any}', toNodeHandler(auth));

any 是任意命名,可以替换为其他标识符。

server.ts
import express from "express";
import { toNodeHandler } from "better-auth/node";
import { auth } from "./auth";

const app = express();
const port = 8000;

app.all("/api/auth/*", toNodeHandler(auth));

// 将 express json 中间件挂载在 Better Auth 处理器之后
// 或仅对不涉及 Better Auth 的路由使用
app.use(express.json());

app.listen(port, () => {
    console.log(`Better Auth 应用已在端口 ${port} 启动`);
});

这也适用于其他 node 服务框架如 express、fastify、hapi 等,但可能需要一些修改。详见 fastify 指南。注意不支持 CommonJS (cjs)。

/pages/api/auth/[...all].ts
import type { APIRoute } from "astro";
import { auth } from "@/auth"; // 你的 auth 文件路径

export const GET: APIRoute = async (ctx) => {
    return auth.handler(ctx.request);
};

export const POST: APIRoute = async (ctx) => {
    return auth.handler(ctx.request);
};
import { Elysia, Context } from "elysia";
import { auth } from "./auth";

const betterAuthView = (context: Context) => {
    const BETTER_AUTH_ACCEPT_METHODS = ["POST", "GET"]
    // 验证请求方法
    if(BETTER_AUTH_ACCEPT_METHODS.includes(context.request.method)) {
        return auth.handler(context.request);
    } else {
        context.error(405)
    }
}

const app = new Elysia().all("/api/auth/*", betterAuthView).listen(3000);

console.log(
`🦊 Elysia 已在 ${app.server?.hostname}:${app.server?.port} 运行`
);
src/routes/api/auth/$.ts
import { auth } from '@/lib/auth'
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute('/api/auth/$')({
    server: {
        handlers: {
            GET: async ({ request }:{ request: Request }) => {
                return await auth.handler(request)
            },
            POST: async ({ request }:{ request: Request }) => {
                return await auth.handler(request)
            },
        },
    },
})

当你调用需要设置 cookie 的函数(如 signInEmailsignUpEmail)时,TanStack Start 需要你处理 cookie 设置。Better Auth 提供 tanstackStartCookies 插件自动处理。

React 版 (TanStack Start + React):

src/lib/auth.ts
import { betterAuth } from "better-auth";
import { tanstackStartCookies } from "better-auth/tanstack-start";

export const auth = betterAuth({
    //...你的配置
    plugins: [tanstackStartCookies()] // 确保是插件数组中的最后一个
})

Solid.js 版 (TanStack Start + Solid):

src/lib/auth.ts
import { betterAuth } from "better-auth";
import { tanstackStartCookies } from "better-auth/tanstack-start/solid";

export const auth = betterAuth({
    //...你的配置
    plugins: [tanstackStartCookies()] // 确保是插件数组中的最后一个
})

这样调用需要设置 cookie 的函数时,将自动通过 TanStack Start 的 cookie 系统完成。

app/api/auth/[...all]+api.ts
import { auth } from '@/lib/server/auth'; // 你的 auth 文件路径

const handler = auth.handler;
export { handler as GET, handler as POST };

创建客户端实例

客户端库帮助你与认证服务器交互。Better Auth 为所有主流 Web 框架及原生 JavaScript 提供客户端。

  1. 从对应框架的包中导入 createAuthClient(例如 React 用 "better-auth/react")。
  2. 调用该函数创建客户端实例。
  3. 传入认证服务器的基础 URL。(如果服务器和客户端运行在同一域名,可跳过)

如果你使用了除 /api/auth 之外的自定义基础路径,请务必传入包含路径的完整 URL。(例如: http://localhost:3000/custom-path/auth

lib/auth-client.ts
import { createAuthClient } from "better-auth/client"
export const authClient = createAuthClient({
    /** 服务器基础 URL(如果和客户端同域, 可选) */
    baseURL: "http://localhost:3000"
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient({
    /** 服务器基础 URL(如果和客户端同域, 可选) */
    baseURL: "http://localhost:3000"
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/vue"
export const authClient = createAuthClient({
    /** 服务器基础 URL(如果和客户端同域, 可选) */
    baseURL: "http://localhost:3000"
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/svelte"
export const authClient = createAuthClient({
    /** 服务器基础 URL(如果和客户端同域, 可选) */
    baseURL: "http://localhost:3000"
})
lib/auth-client.ts
import { createAuthClient } from "better-auth/solid"
export const authClient = createAuthClient({
    /** 服务器基础 URL(如果和客户端同域, 可选) */
    baseURL: "http://localhost:3000"
})

提示:你也可以导出具体方法,若你喜欢这样做:

export const { signIn, signUp, useSession } = createAuthClient()

🎉 就这么简单!

完成了!你现在可以在应用中使用 better-auth 了。继续阅读基础用法了解如何使用 auth 实例进行用户登录。