Auth.js (NextAuth v5) Authentifizierungsmuster
Schnellanleitung: Auth.js wird in einer zentralen
auth.ts-Datei konfiguriert, die{ auth, handlers, signIn, signOut }vonNextAuth()exportiert. Verwende die einheitlicheauth()-Funktion überall (Server Components, Route Handler, Middleware). Die Standard-Session-Strategie ist JWT (cookie-basiert); füge einen Datenbank-Adapter für persistente Sessions hinzu. Schütze Routen über Middleware oder bei Bedarf mitauth()-Aufrufen in jeder Komponente.
<critical_requirements>
KRITISCH: Vor der Nutzung dieses Skills
Der gesamte Code muss den Projektkonventionen in CLAUDE.md folgen (kebab-case, benannte Exporte, Import-Reihenfolge,
import type, benannte Konstanten)
(Du MUSST Auth.js in einer zentralen auth.ts-Datei konfigurieren und { auth, handlers, signIn, signOut } von NextAuth() exportieren)
(Du MUSST die einheitliche auth()-Funktion für den serverseitigen Session-Zugriff verwenden – NICHT die veralteten getServerSession(), getSession() oder getToken())
(Du MUSST die AUTH_SECRET-Umgebungsvariable verwenden – NEXTAUTH_SECRET ist in v5 veraltet)
(Du MUSST AUTH_-präfixierte Umgebungsvariablen für Anbieter-Credentials verwenden (z.B. AUTH_GITHUB_ID, AUTH_GITHUB_SECRET) – sie werden automatisch erkannt)
(Du MUSST die Auth-Konfiguration in auth.config.ts (Edge-kompatibel) und auth.ts (mit Adapter) aufteilen, wenn du Datenbank-Sessions mit Middleware verwendest)
(Du MUSST die Session in Server Actions und API-Routen überprüfen – Middleware allein reicht für die Autorisierung NICHT aus)
</critical_requirements>
Automatische Erkennung: Auth.js, NextAuth, next-auth, authjs, auth.ts, auth.config.ts, NextAuth(), signIn, signOut, auth(), handlers, SessionProvider, useSession, AUTH_SECRET, OAuth-Anbieter, Credentials-Anbieter, Datenbank-Adapter, @auth/prisma-adapter, @auth/drizzle-adapter, authorized-Callback, jwt-Callback, session-Callback, Proxy-Auth, Middleware-Auth
Wann verwenden:
- Hinzufügen von Authentifizierung zu Next.js-, SvelteKit-, Express- oder Qwik-Apps
- Implementieren von OAuth-Login (GitHub, Google, Discord, etc.) mit über 80 integrierten Anbietern
- Erstellen von E-Mail/Magic-Link-Authentifizierungsabläufen
- Bedarf an JWT- oder datenbankgestütztem Session-Management
- Projekte, die Edge-kompatible Middleware-Authentifizierung erfordern
Wann NICHT verwenden:
- Erstellen eines benutzerdefinierten Auth-Systems von Grund auf (Auth.js ist meinungsstark)
- Benötigen von granularer Organisations-/Team-Verwaltung direkt aus der Box
- Nur-Mobile-Apps ohne Web-Frontend
- Benötigen von selbst gehostetem Auth mit Plugin-Architektur
Wichtige abgedeckte Muster:
- Auth-Konfiguration (
auth.ts,auth.config.ts) - OAuth-Anbieter (GitHub, Google, Credentials, E-Mail)
- Session-Strategien (JWT vs. Datenbank)
- Session-Zugriff (Server Components, Route Handler, Client Components)
- Middleware/Proxy-Routenschutz
- Datenbank-Adapter (Prisma, Drizzle)
- Callbacks (jwt, session, signIn, redirect)
- Rollenbasierte Zugriffskontrolle
- Edge-Kompatible geteilte Konfiguration
Detaillierte Ressourcen:
- Für Entscheidungsrahmen und Anti-Patterns siehe reference.md
Kernmuster:
- examples/core.md – Auth-Konfiguration, Anbieter, Callbacks
- examples/session.md – Session-Strategien, Session-Zugriffsmuster
- examples/middleware.md – Routenschutz, Middleware, Edge-Kompatibilität
- examples/database.md – Datenbank-Adapter, Prisma, Drizzle
- examples/patterns.md – Rollenbasierte Zugriffskontrolle, Magic Links, Account-Linking
Philosophie
Auth.js (v5) konsolidiert die Authentifizierung in einer einheitlichen API. Die auth()-Funktion ersetzt getServerSession, getSession, withAuth und getToken aus v4 für die serverseitige Nutzung. useSession() bleibt die korrekte clientseitige API. Die Konfiguration erfolgt in einer zentralen Datei, nicht in API-Routen.
Kernprinzipien:
- Framework-unabhängig – Funktioniert mit Next.js, SvelteKit, Express, Qwik
- Einheitliche API – Einzelne
auth()-Funktion für alle serverseitigen Kontexte - Anbieter-Ökosystem – Über 80 integrierte OAuth-Anbieter mit automatischer Erkennung von
AUTH_*-Umgebungsvariablen - JWT standardmäßig – Zustandslose Sessions in verschlüsselten Cookies, keine Datenbank erforderlich
- Edge-kompatibel – Middleware läuft auf Edge-Runtime mit geteilter Konfiguration (Next.js 16 Proxy läuft auf Node.js)
- Progressive Komplexität – Beginne mit OAuth, füge einen Datenbank-Adapter hinzu, passe dann Callbacks an
Kernmuster
Muster 1: Auth-Konfiguration
Die zentrale Konfigurationsdatei exportiert alles, was du von NextAuth() benötigst.
Einfaches OAuth-Setup
// auth.ts
import NextAuth from "next-auth";
import GitHub from "next-auth/providers/github";
import Google from "next-auth/providers/google";
export const { auth, handlers, signIn, signOut } = NextAuth({
providers: [
GitHub, // Erkennt automatisch AUTH_GITHUB_ID und AUTH_GITHUB_SECRET
Google, // Erkennt automatisch AUTH_GOOGLE_ID und AUTH_GOOGLE_SECRET
],
});
// app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth";
export const { GET, POST } = handlers;
Warum gut: Eine einzige Konfigurationsdatei exportiert alle Auth-Utilities, Anbieter erkennen AUTH_*-Umgebungsvariablen automatisch, die API-Route ist minimal
Umgebungsvariablen
# .env.local
AUTH_SECRET="generate-with-npx-auth-secret" # Erforderlich
AUTH_GITHUB_ID="your-github-client-id" # Wird vom GitHub-Anbieter automatisch erkannt
AUTH_GITHUB_SECRET="your-github-secret" # Wird vom GitHub-Anbieter automatisch erkannt
AUTH_GOOGLE_ID="your-google-id" # Wird vom Google-Anbieter automatisch erkannt
AUTH_GOOGLE_SECRET="your-google-secret"
Warum gut: Das AUTH_-Präfix ist in v5 standardisiert, AUTH_SECRET ersetzt das veraltete NEXTAUTH_SECRET, Anbieter erkennen Credentials automatisch
Muster 2: Anbieter
Auth.js unterstützt OAuth-, E-Mail/Magic Link- und Credentials-Authentifizierung. Über 80 integrierte OAuth-Anbieter erkennen AUTH_*-Umgebungsvariablen automatisch.
// OAuth: Profil-Mapping anpassen
GitHub({
profile(profile) {
return {
id: String(profile.id),
name: profile.name ?? profile.login,
role: "user",
};
},
});
// Credentials: Eingabe validieren, bei Fehler null zurückgeben
Credentials({
async authorize(credentials) {
const parsed = LoginSchema.safeParse(credentials);
if (!parsed.success) return null;
const user = await getUserByEmail(parsed.data.email);
if (
!user ||
!(await verifyPassword(parsed.data.password, user.hashedPassword))
)
return null;
return { id: user.id, name: user.name, email: user.email };
},
});
Wichtige Regeln: Eingabe vor DB-Abfrage validieren, immer Passwörter hashen, bei Fehler null zurückgeben (niemals throw – das gibt Informationen preis). Vollständige Implementierungen findest du in examples/core.md.
Muster 3: Callbacks
Vier Callbacks passen das Auth-Verhalten an. Datenfluss: jwt-Callback (Token anreichern) -> session-Callback (Client bereitstellen).
callbacks: {
jwt({ token, user }) {
if (user) { token.id = user.id; token.role = user.role ?? "user"; }
return token;
},
session({ session, token }) {
session.user.id = token.id as string;
session.user.role = token.role as string;
return session;
},
}
Wichtige Regeln: Der jwt-Callback wird bei JEDEM auth()-Aufruf ausgeführt (leichtgewichtig halten), der user-Parameter ist nur beim Anmelden vorhanden, niemals OAuth-Tokens an den Client weitergeben. Vollständige Callback-Implementierungen inklusive signIn und redirect findest du in examples/core.md.
Muster 4: Session-Zugriff
Die einheitliche auth()-Funktion ersetzt getServerSession, getSession und getToken aus v4 für die serverseitige Nutzung. useSession() bleibt für Client-Komponenten.
| Kontext | So greifst du auf die Session zu |
|---|---|
| Server Component | const session = await auth() |
| Route Handler | export const GET = auth(function GET(req) { req.auth }) |
| Server Action | const session = await auth() |
| Middleware/Proxy | export { auth as middleware } oder authorized-Callback |
| Client Component | useSession() (erfordert SessionProvider im Layout) |
Wichtige Regeln: Serverseitige Importe kommen von @/auth, clientseitige Importe von next-auth/react. Rufe auth() niemals in Client-Komponenten auf. Vollständige Implementierungen findest du in examples/session.md.
Muster 5: Anmelden / Abmelden Aktionen
Zwei Ansätze: Server Actions (empfohlen, progressive Verbesserung) oder clientseitig.
// Serverseitig (empfohlen): Importiere von @/auth, verwende Server Actions in Formularen
import { signIn, signOut } from "@/auth";
// In Form-Aktion: await signIn("github", { redirectTo: "/dashboard" })
// In Form-Aktion: await signOut({ redirectTo: "/" })
// Clientseitig: Importiere von next-auth/react, verwende onClick-Handler
import { signIn, signOut } from "next-auth/react";
// onClick: signIn("github", { callbackUrl: "/dashboard" })
Wichtige Regeln: Serverseitig wird redirectTo verwendet, clientseitig callbackUrl. signIn() wirft intern eine NEXT_REDIRECT-Ausnahme – nicht in try/catch einschließen, wenn ein Rückgabewert erwartet wird. Vollständige Implementierungen findest du in examples/core.md.
Muster 6: TypeScript-Erweiterungen
Erweitere Session- und JWT-Typen durch Deklarations-Merging in types/next-auth.d.ts. Deklariere benutzerdefinierte Felder (z.B. id, role) auf den Interfaces Session, User und JWT mit & DefaultSession["user"], um die Standardfelder zu erhalten. Das vollständige Typdeklarationsbeispiel findest du in examples/core.md.
Integrationsanleitung
Auth.js ist die Authentifizierungsschicht. Sie übernimmt die Identitätsprüfung, das Session-Management und den Routenschutz. Sie übernimmt NICHT die Autorisierungslogik (Rollenprüfungen, Berechtigungssysteme) – das ist Anwendungscode.
Framework-Unterstützung: Auth.js funktioniert mit mehreren Web-Frameworks über frameworkspezifische Pakete (next-auth, @auth/sveltekit, @auth/express).
Datenbank-Adapter: Für Datenbank-Sessions bietet Auth.js Adapter-Pakete (@auth/prisma-adapter, @auth/drizzle-adapter, etc.), die in dein ORM integriert werden. Siehe examples/database.md.
Session-Strategie hängt von deinen Bedürfnissen ab:
- JWT (Standard) – Keine Datenbank nötig, funktioniert auf Edge, zustandslos
- Datenbank – Erfordert Adapter, serverseitiger Session-Speicher, ermöglicht sofortigen Widerruf
Auth.js übernimmt NICHT: feingranulare Autorisierung/RBAC, Ratenbegrenzung oder Datenbankabfragen über die Authentifizierung hinaus – das sind Anwendungsbelange.
<red_flags>
ROTE FLAGGEN
- Verwendung von
getServerSession(authOptions)– in v5 veraltet; verwendeauth()aus deinerauth.ts - Verwendung von
NEXTAUTH_SECREToderNEXTAUTH_URL– veraltet; verwendeAUTH_SECRET(URL wird automatisch erkannt) - Credentials-Anbieter ohne Ratenbegrenzung – anfällig für Brute-Force-Angriffe
- Weitergabe von OAuth-Tokens an den Client über den session-Callback – behalte
accessToken/refreshTokennur serverseitig - Middleware/Proxy als einzige Autorisierung – wird vor dem Rendern ausgeführt, ersetzt aber keine Routenprüfungen in Server Actions/API-Routen
- Datenbank-Adapter in Middleware importiert – Datenbank-ORMs können nicht auf Edge-Runtime laufen (Next.js 14/15); teile die Konfiguration in
auth.config.ts+auth.tsauf signIn()in try/catch einschließen – es wirft intern eine NEXT_REDIRECT-Ausnahme (das ist beabsichtigt)- jwt-Callback, der bei jedem Aufruf die Datenbank abfragt – wird bei JEDER
auth()-Invocierung ausgeführt; halte es leichtgewichtig
Die vollständige Anti-Pattern-Liste, Gotchas und Migrations-Tabelle findest du in reference.md.
</red_flags>
<critical_reminders>
KRITISCHE ERINNERUNGEN
Der gesamte Code muss den Projektkonventionen in CLAUDE.md folgen
(Du MUSST Auth.js in einer zentralen auth.ts-Datei konfigurieren und { auth, handlers, signIn, signOut } von NextAuth() exportieren)
(Du MUSST die einheitliche auth()-Funktion für den serverseitigen Session-Zugriff verwenden – NICHT die veralteten getServerSession(), getSession() oder getToken())
(Du MUSST die AUTH_SECRET-Umgebungsvariable verwenden – NEXTAUTH_SECRET ist in v5 veraltet)
(Du MUSST AUTH_-präfixierte Umgebungsvariablen für Anbieter-Credentials verwenden (z.B. AUTH_GITHUB_ID, AUTH_GITHUB_SECRET) – sie werden automatisch erkannt)
(Du MUSST die Auth-Konfiguration in auth.config.ts (Edge-kompatibel) und auth.ts (mit Adapter) aufteilen, wenn du Datenbank-Sessions mit Middleware verwendest)
(Du MUSST die Session in Server Actions und API-Routen überprüfen – Middleware allein reicht für die Autorisierung NICHT aus)
Die Nichtbeachtung dieser Regeln führt zu Authentifizierungsfehlern, setzt veraltete Muster frei oder verursacht Sicherheitslücken.
</critical_reminders>