4.5 KiB
4.5 KiB
Fix - Authentification avec cookies
Problème identifié
Lors de la création d'un virement dans le modal, l'utilisateur recevait une alerte "Non authentifié".
Cause
Les composants et routes API utilisaient une méthode d'authentification incorrecte :
- Composant client : Tentait de récupérer le token via
supabase.auth.getSession()qui ne fonctionnait pas correctement dans le contexte - Routes API : Attendaient un header
Authorization: Bearer <token>alors que l'application utilise des cookies httpOnly
Solution appliquée
1. Composant client (SalaryTransfersGrid.tsx)
Avant :
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
alert("Non authentifié");
return;
}
const res = await fetch("/api/...", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${session.access_token}`,
},
body: JSON.stringify(data),
});
Après :
const res = await fetch("/api/...", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include", // Envoie automatiquement les cookies
body: JSON.stringify(data),
});
2. Routes API
Avant :
import { createClient } from "@supabase/supabase-js";
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY!;
const supabase = createClient(supabaseUrl, supabaseServiceRoleKey);
const authHeader = req.headers.get("authorization");
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return NextResponse.json({ error: "Missing or invalid Authorization header" }, { status: 401 });
}
const token = authHeader.replace("Bearer ", "");
const { data: { user }, error: authError } = await supabase.auth.getUser(token);
Après :
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
const supabase = createRouteHandlerClient({ cookies });
const { data: { session }, error: sessionError } = await supabase.auth.getSession();
if (sessionError || !session) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
const user = session.user;
3. Vérification Staff
Avant :
const { data: userData, error: userError } = await supabase
.from("users")
.select("is_staff")
.eq("id", user.id)
.single();
if (userError || !userData || !userData.is_staff) {
return NextResponse.json({ error: "Forbidden: staff only" }, { status: 403 });
}
Après :
const { data: staffData, error: staffError } = await supabase
.from("staff_users")
.select("is_staff")
.eq("user_id", user.id)
.maybeSingle();
const isStaff = staffData?.is_staff || false;
if (!isStaff) {
return NextResponse.json({ error: "Forbidden: staff only" }, { status: 403 });
}
Fichiers modifiés
-
components/staff/SalaryTransfersGrid.tsx- Fonction
handleCreateTransfer(): Ajout decredentials: "include", suppression de la récupération du token - Fonction
handleGeneratePdf(): Ajout decredentials: "include", suppression de la récupération du token
- Fonction
-
app/api/staff/virements-salaires/create/route.ts- Import de
createRouteHandlerClientetcookies - Utilisation de
getSession()au lieu degetUser(token) - Vérification dans la table
staff_usersau lieu deusers
- Import de
-
app/api/staff/virements-salaires/generate-pdf/route.ts- Import de
createRouteHandlerClientetcookies - Utilisation de
getSession()au lieu degetUser(token) - Vérification dans la table
staff_usersau lieu deusers
- Import de
Conformité avec le reste du code
Cette approche est maintenant cohérente avec les autres routes API du projet, notamment :
app/api/informations/route.tsapp/api/tickets/route.tsapp/api/contrats/[id]/paies/route.ts
Tests à effectuer
- ✅ Créer un virement via le modal
- ✅ Générer un PDF pour un virement
- ✅ Vérifier que l'authentification fonctionne
- ✅ Vérifier que seuls les utilisateurs Staff peuvent accéder
Avantages de cette approche
- Sécurité : Les cookies httpOnly ne sont pas accessibles via JavaScript
- Simplicité : Pas besoin de gérer manuellement les tokens côté client
- Cohérence : Utilise la même méthode que le reste de l'application
- Automatique : Les cookies sont envoyés automatiquement avec
credentials: "include"
Date du fix
13 octobre 2025