Next.js Auth (Auth.js v5)
Regeln
- Konfiguration in
auth.ts zentralisieren (NextAuth() Export: handlers, auth, signIn, signOut). Provider-Geheimnisse niemals verstreuen.
- Routen in
middleware.ts schützen (Edge-sicherer auth-Wrapper) und Session innerhalb von Server Actions/Mutationen erneut prüfen – Middleware ist UX, nicht Autorisierung.
- Session in Server Components über
await auth() lesen. In Client Components useSession() von next-auth/react mit <SessionProvider> verwenden.
- Geheimnisse (
AUTH_SECRET, Provider-Schlüssel) niemals mit NEXT_PUBLIC_-Präfix exponieren. Env-Variablen beim Start mit Zod validieren.
- Rollenprüfungen: Session-Typ über Modulaugmentation erweitern (
user.role), serverseitig durchsetzen.
Patterns
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 }
}
Checkliste