Next.js 集成

Better Auth可以轻松地与Next.js集成。它还提供了一些实用工具,使Better Auth更容易与Next.js一起使用。

在开始之前,请确保你已经配置了 Better Auth 实例。如果你尚未完成此操作,请查看安装指南

创建 API 路由

我们需要将处理程序挂载到 API 路由。在 /api/auth/[...all] 目录内创建一个路由文件。并添加以下代码:

api/auth/[...all]/route.ts
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
 
export const { GET, POST } = toNextJsHandler(auth.handler);

你可以在 better-auth 配置中更改路径,但建议保持为 /api/auth/[...all]

对于 pages 路由,你需要使用 toNodeHandler 而不是 toNextJsHandler,并在 config 对象中将 bodyParser 设置为 false。这是一个例子:

pages/api/auth/[...all].ts
import { toNodeHandler } from "better-auth/node"
import { auth } from "@/lib/auth"
 
// 禁止自动解析请求体,我们将手动解析
export const config = { api: { bodyParser: false } }
 
export default toNodeHandler(auth.handler)

创建客户端

创建一个客户端实例。你可以给文件取任何你想要的名字。这里我们在 lib/ 目录下创建 client.ts 文件。

auth-client.ts
import { createAuthClient } from "better-auth/react" // 确保从 better-auth/react 导入
 
export const authClient =  createAuthClient({
    //你可以在这里传递客户端配置
})

一旦你创建了客户端,你就可以使用它来注册、登录和执行其他操作。 其中一些操作是响应式的。客户端使用 nano-store 存储状态,并在状态变化时重新渲染组件。

客户端还使用 better-fetch 来发送请求。你可以将 fetch 配置传递给客户端。

RSC 和服务器操作

从 auth 实例导出的 api 对象包含了你可以在服务器上执行的所有操作。Better Auth 内部的每个端点都可以作为函数调用。包括插件端点。

示例:在服务器操作中获取会话

server.ts
import { auth } from "@/lib/auth"
import { headers } from "next/headers"
 
const someAuthenticatedAction = async () => {
    "use server";
    const session = await auth.api.getSession({
        headers: await headers()
    })
};

示例:在 RSC 中获取会话

import { auth } from "@/lib/auth"
import { headers } from "next/headers"
 
export async function ServerComponent() {
    const session = await auth.api.getSession({
        headers: await headers()
    })
    if(!session) {
        return <div>未认证</div>
    }
    return (
        <div>
            <h1>欢迎 {session.user.name}</h1>
        </div>
    )
}

服务器操作中的 Cookies

当你在服务器操作中调用需要设置 cookies 的函数,比如 signInEmailsignUpEmail 时,cookies 不会被设置。这是因为服务器操作需要使用 Next.js 的 cookies 帮助函数来设置 cookies。

为了简化这一点,你可以使用 nextCookies 插件,它会在响应中存在 Set-Cookie 头时自动为你设置 cookies。

auth.ts
import { betterAuth } from "better-auth";
import { nextCookies } from "better-auth/next-js";
 
export const auth = betterAuth({
    //...你的配置
    plugins: [nextCookies()] // 确保这是数组中的最后一个插件
})

现在,当你调用设置 cookies 的函数时,它们将自动被设置。

"use server";
import { auth } from "@/lib/auth"
 
const signIn = async () => {
    await auth.api.signInEmail({
        body: {
            email: "[email protected]",
            password: "password",
        }
    })
}

中间件

在 Next.js 中间件中,建议只检查会话 cookie 的存在与否来处理重定向。避免通过进行 API 或数据库调用来阻塞请求。

你可以使用 Better Auth 的 getSessionCookie 辅助函数来实现这一点:

getSessionCookie() 函数不会自动引用 auth.ts 中指定的 auth 配置。因此,你需要确保 getSessionCookie() 中的配置与你在 auth.ts 中定义的配置相匹配。

import { NextRequest, NextResponse } from "next/server";
import { getSessionCookie } from "better-auth/cookies";
 
export async function middleware(request: NextRequest) {
	const sessionCookie = getSessionCookie(request);
 
	if (!sessionCookie) {
		return NextResponse.redirect(new URL("/", request.url));
	}
 
	return NextResponse.next();
}
 
export const config = {
	matcher: ["/dashboard"], // 指定中间件适用的路由
};

如果你有自定义的 cookie 名称或前缀,你可以将其传递给 getSessionCookie 函数。

const sessionCookie = getSessionCookie(request, {
    cookieName: "my_session_cookie",
    cookiePrefix: "my_prefix"
});

对于 Next.js 版本 15.1.7 及以下

如果你需要完整的会话对象,你必须从 /get-session API 路由获取它。由于 Next.js 中间件不支持直接运行 Node.js API,你必须发起 HTTP 请求。

此示例使用 better-fetch,但你可以使用任何 fetch 库。

import { betterFetch } from "@better-fetch/fetch";
import type { auth } from "@/lib/auth";
import { NextRequest, NextResponse } from "next/server";
 
type Session = typeof auth.$Infer.Session;
 
export async function middleware(request: NextRequest) {
	const { data: session } = await betterFetch<Session>("/api/auth/get-session", {
		baseURL: request.nextUrl.origin,
		headers: {
			cookie: request.headers.get("cookie") || "", // 转发请求中的 cookies
		},
	});
 
	if (!session) {
		return NextResponse.redirect(new URL("/sign-in", request.url));
	}
 
	return NextResponse.next();
}
 
export const config = {
	matcher: ["/dashboard"], // 将中间件应用于特定路由
};

对于 Next.js 版本 15.2.0 及以上

从版本 15.2.0 开始,Next.js 允许你在中间件中使用 Node.js 运行时。这意味着你可以直接在中间件中使用 auth.api 对象。

你可以参考 Next.js 文档 了解更多关于运行时配置以及如何启用它的信息。 使用新运行时时要小心。这是一个实验性功能,可能会有破坏性变更。

import { NextRequest, NextResponse } from "next/server";
import { headers } from "next/headers";
import { auth } from "@/lib/auth";
 
export async function middleware(request: NextRequest) {
    const session = await auth.api.getSession({
        headers: await headers()
    })
 
    if(!session) {
        return NextResponse.redirect(new URL("/sign-in", request.url));
    }
 
    return NextResponse.next();
}
 
export const config = {
  runtime: "nodejs",
  matcher: ["/dashboard"], // 将中间件应用于特定路由
};

On this page