# Better Auth Fastify 集成指南 (/docs/integrations/fastify)

了解如何将 Better Auth 无缝集成到您的 Fastify 应用程序中。



本指南提供了配置基本处理程序和 CORS 设置的逐步说明。

<Callout type="important">
  在继续之前，需要配置一个 Better Auth 实例。如果尚未设置，请参考我们的 [安装指南](/docs/installation)。
</Callout>

### 前提条件 [#前提条件]

在集成之前，请确认满足以下要求：

* **Node.js 环境**: 已安装 v16 或更高版本
* **ES 模块支持**: 在以下任一选项中启用 ES 模块：
  * `package.json`: `{ "type": "module" }`
  * TypeScript `tsconfig.json`: `{ "module": "ESNext" }`
* **Fastify 依赖项**:
  <CodeBlockTabs defaultValue="npm" groupId="persist-install">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="npm">
        npm
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="pnpm">
        pnpm
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="yarn">
        yarn
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="bun">
        bun
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="npm">
      ```bash
      npm install fastify @fastify/cors
      ```
    </CodeBlockTab>

    <CodeBlockTab value="pnpm">
      ```bash
      pnpm add fastify @fastify/cors
      ```
    </CodeBlockTab>

    <CodeBlockTab value="yarn">
      ```bash
      yarn add fastify @fastify/cors
      ```
    </CodeBlockTab>

    <CodeBlockTab value="bun">
      ```bash
      bun add fastify @fastify/cors
      ```
    </CodeBlockTab>
  </CodeBlockTabs>

<Callout type="tip">
   对于 TypeScript 用户：请确保 

  `tsconfig.json`

   包含 

  `"esModuleInterop": true`

  ，以获得最佳兼容性。 
</Callout>

### 认证处理程序设置 [#认证处理程序设置]

通过创建一个通配路由来配置 Better Auth 以处理身份验证请求：

```ts title="server.ts"
import Fastify from "fastify";
import { fromNodeHeaders } from "better-auth/node";
import { auth } from "./auth"; // 您配置好的 Better Auth 实例

const fastify = Fastify({ logger: true });

// 注册认证端点
fastify.route({
  method: ["GET", "POST"],
  url: "/api/auth/*",
  async handler(request, reply) {
    try {
      // 构造请求 URL
      const url = new URL(request.url, `http://${request.headers.host}`);
      
      // 将 Fastify 请求头转换为标准 Headers 对象
      const headers = fromNodeHeaders(request.headers);

      // 创建兼容 Fetch API 的请求对象
      const req = new Request(url.toString(), {
        method: request.method,
        headers,
        ...(request.body ? { body: JSON.stringify(request.body) } : {}),
      });

      // 处理身份验证请求
      const response = await auth.handler(req);

      // 将响应转发给客户端
      reply.status(response.status);
      response.headers.forEach((value, key) => reply.header(key, value));
      return reply.send(response.body ? await response.text() : null);
    } catch (error) {
      fastify.log.error("Authentication Error:", error);
      return reply.status(500).send({ 
        error: "内部身份验证错误",
        code: "AUTH_FAILURE"
      });
    }
  }
});

// 启动服务器
fastify.listen({ port: 4000 }, (err) => {
  if (err) {
    fastify.log.error(err);
    process.exit(1);
  }
  console.log("服务器运行在 4000 端口");
});
```

### 受信任的来源 [#受信任的来源]

当请求来自不同来源时，默认会被阻止。您可以向 `auth` 实例添加受信任来源。

```ts
export const auth = betterAuth({
  trustedOrigins: ["http://localhost:3000", "https://example.com"],
});
```

### 配置 CORS [#配置-cors]

通过正确配置 CORS 来保护您的 API 端点：

```ts
import fastifyCors from "@fastify/cors";

// 配置 CORS 策略
fastify.register(fastifyCors, {
  origin: process.env.CLIENT_ORIGIN || "http://localhost:3000",
  methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
  allowedHeaders: [
    "Content-Type",
    "Authorization",
    "X-Requested-With"
  ],
  credentials: true,
  maxAge: 86400
});

// 在注册 CORS 后挂载认证处理程序
// （使用前面所示的处理程序配置）
```

<Callout type="warning">
   在生产环境中，请始终限制 CORS 来源。使用环境变量实现动态配置。 
</Callout>

### 获取用户会话 [#获取用户会话]

在您的 Fastify 路由中获取用户会话，请使用 `auth.api.getSession` 方法。Better Auth 提供了 `fromNodeHeaders` 辅助函数，用于将 Node.js 请求头转换为 Better Auth 期望的格式。

```ts title="server.ts"
import { fromNodeHeaders } from "better-auth/node";
import { auth } from "./auth"; // 您的 Better Auth 实例

fastify.get("/api/me", async (request, reply) => {
  const session = await auth.api.getSession({
    headers: fromNodeHeaders(request.headers),
  });

  if (!session) {
    return reply.status(401).send({ error: "未授权" });
  }

  return reply.send(session);
});
```

