Next.js 身份验证 (Auth.js v5) 是做什么的?
规则
- 在
auth.ts 中集中配置(NextAuth() 导出:handlers、auth、signIn、signOut)。切勿分散提供者密钥。
- 在
middleware.ts 中保护路由(使用边缘安全的 auth 包装器),并在服务端操作/变更中重新检查会话 —— 中间件是用户体验,而非授权。
- 在服务端组件中通过
await auth() 读取会话。在客户端组件中使用来自 next-auth/react 的 useSession(),并配合 <SessionProvider>。
- 切勿使用
NEXT_PUBLIC_ 前缀暴露密钥(AUTH_SECRET、提供者密钥)。在启动时使用 Zod 验证环境变量。
- 角色检查:通过模块扩充扩展会话类型(
user.role),在服务端强制执行。
模式
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [GitHub],
callbacks: {
async session({ session, token }) {
if (session.user) (session.user as { role?: string }).role = token.role as string;
return session;
},
async jwt({ token, user }) {
if (user) token.role = (user as { role?: string }).role ?? 'user';
return token;
},
},
});
export { auth as middleware } from '@/auth';
export const config = { matcher: ['/dashboard/:path*', '/admin/:path*'] };
import { handlers } from '@/auth';
export const { GET, POST } = handlers;
import { auth } from '@/auth';
import { redirect } from 'next/navigation';
export default async function AdminPage() {
const session = await auth();
if (!session?.user) redirect('/login');
if ((session.user as { role?: string }).role !== 'admin')
redirect('/dashboard');
return <AdminView />;
}
import 'next-auth';
declare module 'next-auth' {
interface User { role?: string }
}
检查清单