Astro 集成
Better Auth 为 Astro 提供了一流的支持。本指南将展示如何将 Better Auth 与 Astro 集成。
在开始之前,请确保您已配置好 Better Auth 实例。如果尚未完成,请查看安装指南。
挂载处理程序
为了让 Better Auth 能够处理请求,我们需要将其处理程序挂载到一个全捕获 API 路由。在 /pages/api/auth
目录下创建一个名为 [...all].ts
的文件,并添加以下代码:
import { auth } from "~/auth";
import type { APIRoute } from "astro";
export const ALL: APIRoute = async (ctx) => {
// 如果您想使用速率限制,请确保将 'x-forwarded-for' 头设置为来自上下文的请求头
// ctx.request.headers.set("x-forwarded-for", ctx.clientAddress);
return auth.handler(ctx.request);
};
您可以在 better-auth 配置中更改路径,但建议保持为 /api/auth/[...all]
创建客户端
Astro 支持多种前端框架,因此您可以根据所使用的框架轻松导入对应的客户端。
如果您不使用前端框架,仍然可以导入原生客户端。
import { createAuthClient } from "better-auth/client"
export const authClient = createAuthClient()
import { createAuthClient } from "better-auth/react"
export const authClient = createAuthClient()
import { createAuthClient } from "better-auth/vue"
export const authClient = createAuthClient()
import { createAuthClient } from "better-auth/svelte"
export const authClient = createAuthClient()
import { createAuthClient } from "better-auth/solid"
export const authClient = createAuthClient()
认证中间件
Astro Locals 类型
要为您的 Astro locals 提供类型支持,需要在 env.d.ts
文件中进行设置。
/// <reference path="../.astro/types.d.ts" />
declare namespace App {
// 注意:在 .d.ts 文件中不能使用 'import {} from ""' 语法
interface Locals {
user: import("better-auth").User | null;
session: import("better-auth").Session | null;
}
}
中间件
要保护您的路由,可以在中间件中使用 getSession
方法检查用户是否已认证,并使用我们之前设置的类型通过 Astro locals 设置用户和会话数据。首先在项目根目录创建 middleware.ts
文件,并按照以下示例操作:
import { auth } from "@/auth";
import { defineMiddleware } from "astro:middleware";
export const onRequest = defineMiddleware(async (context, next) => {
const isAuthed = await auth.api
.getSession({
headers: context.request.headers,
})
if (isAuthed) {
context.locals.user = isAuthed.user;
context.locals.session = isAuthed.session;
} else {
context.locals.user = null;
context.locals.session = null;
}
return next();
});
在 .astro
文件中获取服务器端会话
您可以使用 Astro.locals
检查用户是否有会话,并从服务器端获取用户数据。以下是在 .astro
文件中获取会话的示例:
---
import { UserCard } from "@/components/user-card";
const session = () => {
if (Astro.locals.session) {
return Astro.locals.session;
} else {
// 如果用户未认证,重定向到登录页面
return Astro.redirect("/login");
}
}
---
<UserCard initialSession={session} />