Next.js 集成
Better Auth 可以轻松地与 Next.js 集成。在开始之前,请确保你已配置了 Better Auth 实例。如果还没有配置,请查看安装指南。
🌐 Better Auth can be easily integrated with Next.js. Before you start, make sure you have a Better Auth instance configured. If you haven't done that yet, check out the installation.
创建 API 路由
🌐 Create API Route
我们需要将处理程序挂载到一个 API 路由。请在 /api/auth/[...all] 目录下创建一个路由文件,并添加以下代码:
🌐 We need to mount the handler to an API route. Create a route file inside /api/auth/[...all] directory. And add the following code:
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
export const { GET, POST } = toNextJsHandler(auth);你可以在 better-auth 配置中更改路径,但建议保持为 /api/auth/[...all]
对于 pages 路由,你需要使用 toNodeHandler 而不是 toNextJsHandler,并在 config 对象中将 bodyParser 设置为 false。以下是一个示例:
🌐 For pages route, you need to use toNodeHandler instead of toNextJsHandler and set bodyParser to false in the config object. Here is an example:
import { toNodeHandler } from "better-auth/node"
import { auth } from "@/lib/auth"
// Disallow body parsing, we will parse it manually
export const config = { api: { bodyParser: false } }
export default toNodeHandler(auth.handler)创建客户端
🌐 Create a client
创建一个客户端实例。你可以随意命名文件。在这里,我们在 lib/ 目录下创建 auth-client.ts 文件。
🌐 Create a client instance. You can name the file anything you want. Here we are creating auth-client.ts file inside the lib/ directory.
import { createAuthClient } from "better-auth/react" // make sure to import from better-auth/react
export const authClient = createAuthClient({
//you can pass client configuration here
})一旦你创建了客户端,就可以使用它进行注册、登录以及执行其他操作。 其中一些操作是响应式的。客户端使用 nano-store 来存储状态,并在状态变化时重新渲染组件。
🌐 Once you have created the client, you can use it to sign up, sign in, and perform other actions. Some of the actions are reactive. The client uses nano-store to store the state and re-render the components when the state changes.
客户端还使用 better-fetch 来发起请求。你可以将 fetch 配置传递给客户端。
🌐 The client also uses better-fetch to make the requests. You can pass the fetch configuration to the client.
RSC 和服务器操作
🌐 RSC and Server actions
从 auth 实例导出的 api 对象包含了你可以在服务器上执行的所有操作。在 Better Auth 中创建的每个端点都可以作为函数调用,包括插件端点。
🌐 The api object exported from the auth instance contains all the actions that you can perform on the server. Every endpoint made inside Better Auth is a invocable as a function. Including plugins endpoints.
示例:在服务器操作中获取会话
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>Not authenticated</div>
}
return (
<div>
<h1>Welcome {session.user.name}</h1>
</div>
)
}服务器操作 Cookie
🌐 Server Action Cookies
当你在服务器操作中调用需要设置 cookie 的函数时,例如 signInEmail 或 signUpEmail,cookie 不会被设置。这是因为服务器操作需要使用 Next.js 提供的 cookies 工具来设置 cookie。
🌐 When you call a function that needs to set cookies, like signInEmail or signUpEmail in a server action, cookies won’t be set. This is because server actions need to use the cookies helper from Next.js to set cookies.
为简化这个过程,你可以使用 nextCookies 插件,它会在响应中存在 Set-Cookie 头时自动为你设置 cookie。
🌐 To simplify this, you can use the nextCookies plugin, which will automatically set cookies for you whenever a Set-Cookie header is present in the response.
import { betterAuth } from "better-auth";
import { nextCookies } from "better-auth/next-js";
export const auth = betterAuth({
//...your config
plugins: [nextCookies()] // make sure this is the last plugin in the array
})现在,当你调用设置 cookies 的函数时,它们会被自动设置。
🌐 Now, when you call functions that set cookies, they will be automatically set.
"use server";
import { auth } from "@/lib/auth"
const signIn = async () => {
await auth.api.signInEmail({
body: {
email: "user@email.com",
password: "password",
}
})
}身份验证保护
🌐 Auth Protection
在 Next.js 的代理/中间件中,建议仅检查会话 cookie 是否存在来处理重定向。这样可以避免通过调用 API 或数据库而阻塞请求。
🌐 In Next.js proxy/middleware, it's recommended to only check for the existence of a session cookie to handle redirection. To avoid blocking requests by making API or database calls.
Next.js 16+(代理)
🌐 Next.js 16+ (Proxy)
Next.js 16 用 "proxy" 替代了 "middleware"。你可以使用 Node.js 运行时进行完整的会话验证并进行数据库检查:
🌐 Next.js 16 replaces "middleware" with "proxy". You can use the Node.js runtime for full session validation with database checks:
import { NextRequest, NextResponse } from "next/server";
import { headers } from "next/headers";
import { auth } from "@/lib/auth";
export async function proxy(request: NextRequest) {
const session = await auth.api.getSession({
headers: await headers()
})
// THIS IS NOT SECURE!
// This is the recommended approach to optimistically redirect users
// We recommend handling auth checks in each page/route
if(!session) {
return NextResponse.redirect(new URL("/sign-in", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard"], // Specify the routes the middleware applies to
};对于仅使用 Cookie 的检查(更快但安全性较低),请使用 getSessionCookie:
🌐 For cookie-only checks (faster but less secure), use getSessionCookie:
import { NextRequest, NextResponse } from "next/server";
import { getSessionCookie } from "better-auth/cookies";
export async function proxy(request: NextRequest) {
const sessionCookie = getSessionCookie(request);
// THIS IS NOT SECURE!
// This is the recommended approach to optimistically redirect users
// We recommend handling auth checks in each page/route
if (!sessionCookie) {
return NextResponse.redirect(new URL("/", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard"], // Specify the routes the middleware applies to
};**从中间件迁移:**将 middleware.ts 重命名为 proxy.ts,将 middleware 函数重命名为 proxy。所有 Better Auth 方法的使用方式保持不变。
Next.js 15.2.0+(Node.js 运行时中间件)
🌐 Next.js 15.2.0+ (Node.js Runtime Middleware)
从 Next.js 15.2.0 开始,你可以在中间件中使用 Node.js 运行时,通过数据库检查实现完整的会话验证:
🌐 From Next.js 15.2.0, you can use the Node.js runtime in middleware for full session validation with database checks:
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()
})
// THIS IS NOT SECURE!
// This is the recommended approach to optimistically redirect users
// We recommend handling auth checks in each page/route
if(!session) {
return NextResponse.redirect(new URL("/sign-in", request.url));
}
return NextResponse.next();
}
export const config = {
runtime: "nodejs", // Required for auth.api calls
matcher: ["/dashboard"], // Specify the routes the middleware applies to
};在 Next.js 16 之前的版本中,中间件中的 Node.js 运行时仍处于实验阶段。建议升级到 Next.js 16 或更高版本以获得稳定的代理支持。
Next.js 13-15.1.x(Edge 运行时中间件)
🌐 Next.js 13-15.1.x (Edge Runtime Middleware)
在较旧的 Next.js 版本中,中间件在 Edge Runtime 上运行,无法进行数据库调用。使用基于 cookie 的检查来进行乐观重定向:
🌐 In older Next.js versions, middleware runs on the Edge Runtime and cannot make database calls. Use cookie-based checks for optimistic redirects:
getSessionCookie() 函数不会自动引用 auth.ts 中指定的认证配置。因此,如果你自定义了 cookie 名称或前缀,你需要确保 getSessionCookie() 中的配置与 auth.ts 中定义的配置匹配。
对于 Next.js 版本 15.1.7 及以下
🌐 For Next.js release 15.1.7 and below
如果你需要完整的会话对象,你必须从 /api/auth/get-session API 路由获取它。由于 Next.js 中间件不支持直接运行 Node.js API,你必须发起一个 HTTP 请求。
🌐 If you need the full session object, you'll have to fetch it from the /api/auth/get-session API route. Since Next.js middleware doesn't support running Node.js APIs directly, you must make an HTTP request.
这个示例使用了 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") || "", // Forward the cookies from the request
},
});
if (!session) {
return NextResponse.redirect(new URL("/sign-in", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard"], // Apply middleware to specific routes
};适用于 Next.js 版本 15.2.0 及以上
🌐 For Next.js release 15.2.0 and above
从 Next.js 15.2.0 开始,你可以在中间件中使用 Node.js 运行时,通过数据库检查实现完整的会话验证:
🌐 From Next.js 15.2.0, you can use the Node.js runtime in middleware for full session validation with database checks:
你可以参考 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"], // Apply middleware to specific routes
};基于 Cookie 的检查(推荐用于所有版本)
🌐 Cookie-based checks (recommended for all versions)
import { NextRequest, NextResponse } from "next/server";
import { getSessionCookie } from "better-auth/cookies";
export async function middleware(request: NextRequest) {
const sessionCookie = getSessionCookie(request);
// THIS IS NOT SECURE!
// This is the recommended approach to optimistically redirect users
// We recommend handling auth checks in each page/route
if (!sessionCookie) {
return NextResponse.redirect(new URL("/", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard"], // Specify the routes the middleware applies to
};安全警告: getSessionCookie 函数仅检查会话 cookie 是否存在;它不会验证 cookie 的有效性。仅依赖此检查来保障安全是危险的,因为任何人都可以手动创建一个 cookie 来绕过检查。对于任何受保护的操作或页面,你必须始终在服务器端验证会话。
如果你有自定义的 cookie 名称或前缀,可以将其传递给 getSessionCookie 函数。
const sessionCookie = getSessionCookie(request, {
cookieName: "my_session_cookie",
cookiePrefix: "my_prefix"
});或者,你可以使用 getCookieCache 辅助函数从 cookie 缓存中获取会话对象。
🌐 Alternatively, you can use the getCookieCache helper to get the session object from the cookie cache.
import { getCookieCache } from "better-auth/cookies";
export async function middleware(request: NextRequest) {
const session = await getCookieCache(request);
if (!session) {
return NextResponse.redirect(new URL("/sign-in", request.url));
}
return NextResponse.next();
}如何在每个页面/路由中处理身份验证检查
🌐 How to handle auth checks in each page/route
在此示例中,我们在服务器组件中使用 auth.api.getSession 函数获取会话对象,然后检查会话是否有效。如果无效,我们会将用户重定向到登录页面。
🌐 In this example, we are using the auth.api.getSession function within a server component to get the session object,
then we are checking if the session is valid. If it's not, we are redirecting the user to the sign-in page.
import { auth } from "@/lib/auth";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
export default async function DashboardPage() {
const session = await auth.api.getSession({
headers: await headers()
})
if(!session) {
redirect("/sign-in")
}
return <h1>Welcome {session.user.name}</h1>
}Next.js 16 兼容性
🌐 Next.js 16 Compatibility
Better Auth 完全兼容 Next.js 16。主要的变化是“middleware”现在被称为“proxy”。有关 Next.js 16 及以上版本 proxy 的示例,请参见上面的 Auth Protection 部分。
🌐 Better Auth is fully compatible with Next.js 16. The main change is that "middleware" is now called "proxy". See the Auth Protection section above for Next.js 16+ proxy examples.
迁移指南
🌐 Migration Guide
使用 Next.js codemod 进行自动迁移:
🌐 Use Next.js codemod for automatic migration:
npx @next/codemod@canary middleware-to-proxy .或者手动:
🌐 Or manually:
- 将
middleware.ts重命名为proxy.ts - 更改函数名:
middleware→proxy
所有 Better Auth 方法的工作方式都是相同的。详情请参阅 Next.js 迁移指南。
🌐 All Better Auth methods work identically. See the Next.js migration guide for details.