update nextauth
This commit is contained in:
parent
c8a5f9e04d
commit
0fd0cda405
@ -12,24 +12,24 @@ datasource db {
|
||||
model Account {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
type String
|
||||
provider String
|
||||
providerAccountId String
|
||||
type String // z.B. "oauth", "oidc"
|
||||
provider String // z.B. "keycloak", "credentials"
|
||||
providerAccountId String // Die ID des Benutzers beim Provider (z.B. Keycloak 'sub')
|
||||
refresh_token String? @db.Text
|
||||
access_token String? @db.Text
|
||||
expires_at Int? // Üblicherweise für access_token Ablauf (in Sekunden seit Unix-Epoche)
|
||||
token_type String?
|
||||
expires_at Int? // Unix-Timestamp (in Sekunden) für den Ablauf des access_token
|
||||
token_type String? // z.B. "Bearer"
|
||||
scope String?
|
||||
id_token String? @db.Text
|
||||
session_state String?
|
||||
|
||||
refresh_expires_in Int? // NEU: Lebensdauer des Refresh Tokens in Sekunden
|
||||
not_before_policy Int? // NEU: Keycloak "Not Before Policy" Wert (Unix-Timestamp)
|
||||
refresh_expires_in Int? // Lebensdauer des Refresh Tokens in Sekunden
|
||||
not_before_policy Int? // NEU: Keycloak "Not Before Policy" Wert (oft ein Timestamp)
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([provider, providerAccountId])
|
||||
@@index([userId]) // Index für userId hinzugefügt für bessere Abfrageleistung
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
model Session {
|
||||
|
||||
@ -7,15 +7,14 @@ import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||
import prisma from "../../../lib/prisma";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
import type { User } from "next-auth";
|
||||
import type { User, Account } from "next-auth"; // Account importieren für den signIn Callback
|
||||
|
||||
export const authOptions: AuthOptions = {
|
||||
adapter: PrismaAdapter(prisma),
|
||||
session: {
|
||||
strategy: "jwt",
|
||||
},
|
||||
// Debug-Modus für ausführlichere Logs von NextAuth.js aktivieren
|
||||
debug: true, // process.env.NODE_ENV === 'development',
|
||||
debug: process.env.NODE_ENV === 'development',
|
||||
providers: [
|
||||
KeycloakProvider({
|
||||
clientId: process.env.KEYCLOAK_CLIENT_ID as string,
|
||||
@ -23,14 +22,11 @@ export const authOptions: AuthOptions = {
|
||||
issuer: process.env.KEYCLOAK_ISSUER as string,
|
||||
allowDangerousEmailAccountLinking: true,
|
||||
profile(profile: KeycloakProfile, tokens: TokenSet): User | Promise<User> {
|
||||
// Detailliertes Logging des empfangenen Keycloak-Profils und der Tokens
|
||||
console.log("[NextAuth.js] Keycloak Profile Received:", JSON.stringify(profile, null, 2));
|
||||
// Vorsicht beim Loggen von Tokens in der Produktion, hier nur ein Snippet des ID-Tokens
|
||||
if (tokens.id_token) {
|
||||
console.log("[NextAuth.js] Keycloak ID Token Snippet:", tokens.id_token.substring(0, 50) + "...");
|
||||
}
|
||||
|
||||
|
||||
let userRole = 'user';
|
||||
if (profile.realm_access?.roles && Array.isArray(profile.realm_access.roles) && profile.realm_access.roles.includes('admin')) {
|
||||
userRole = 'admin';
|
||||
@ -38,22 +34,20 @@ export const authOptions: AuthOptions = {
|
||||
userRole = 'admin';
|
||||
}
|
||||
|
||||
const emailFromProvider = profile.email?.toLowerCase(); // E-Mail normalisieren (zu Kleinbuchstaben)
|
||||
const emailFromProvider = profile.email?.toLowerCase();
|
||||
|
||||
if (!emailFromProvider) {
|
||||
console.error("[NextAuth.js] Email not provided by Keycloak profile. Profile data:", profile);
|
||||
// Du könntest hier entscheiden, einen Fehler zu werfen oder einen Fallback zu implementieren,
|
||||
// aber für die Kontoverknüpfung ist eine E-Mail essentiell.
|
||||
throw new Error("E-Mail wurde nicht vom Identitätsprovider (Keycloak) bereitgestellt.");
|
||||
}
|
||||
|
||||
const userToReturn: User = {
|
||||
id: profile.sub,
|
||||
name: profile.name || profile.preferred_username,
|
||||
email: emailFromProvider, // Normalisierte E-Mail verwenden
|
||||
email: emailFromProvider,
|
||||
image: profile.picture,
|
||||
role: userRole,
|
||||
isApproved: true, // Annahme: OIDC-Benutzer sind standardmäßig freigegeben
|
||||
isApproved: true,
|
||||
};
|
||||
|
||||
console.log("[NextAuth.js] User object to be processed by adapter/callbacks:", JSON.stringify(userToReturn, null, 2));
|
||||
@ -95,6 +89,22 @@ export const authOptions: AuthOptions = {
|
||||
}),
|
||||
],
|
||||
callbacks: {
|
||||
// NEU: signIn Callback, um Account-Daten vor dem Speichern anzupassen
|
||||
async signIn({account}) {
|
||||
if (account && account.provider === "keycloak") {
|
||||
// Prüfe, ob 'not-before-policy' im Account-Objekt von Keycloak vorhanden ist
|
||||
// und benenne es in 'not_before_policy' um, damit es zum Prisma-Schema passt.
|
||||
// Das account-Objekt hier enthält die rohen Daten vom Token-Endpunkt.
|
||||
const keycloakAccount = account as Account & { 'not-before-policy'?: any, 'not_before_policy'?: any };
|
||||
|
||||
if (keycloakAccount['not-before-policy'] !== undefined) {
|
||||
console.log(`[NextAuth.js] signIn callback: Renaming 'not-before-policy' to 'not_before_policy' for account: ${account.providerAccountId}`);
|
||||
keycloakAccount.not_before_policy = keycloakAccount['not-before-policy'];
|
||||
delete keycloakAccount['not-before-policy'];
|
||||
}
|
||||
}
|
||||
return true; // Erlaube den Anmeldevorgang
|
||||
},
|
||||
async jwt({ token, user, account }) {
|
||||
if (account && user) {
|
||||
token.id = user.id;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user