🚨 PROBLEMA CRITICO AUTENTICAZIONE - ROOT CAUSE TROVATO
Il Problema
Il sistema di login è clamorosamente rotto perché la stragrande maggioranza delle chiamate fetch() nell’applicazione NON include credentials: "include".
Cosa succede:
- Utente fa login → cookie
auth-tokenviene impostato ✅ - Browser fa redirect a
/→ middleware verifica cookie ✅ - La dashboard fa 10+ chiamate API fetch SENZA
credentials: "include"❌ - Le API ricevono richieste SENZA cookie ❌
- Middleware/auth ritorna 401 Unauthorized ❌
- Utente viene buttato fuori casualmente ❌
Evidenze
Chiamate SENZA credentials trovate:
/src/app/(dashboard)/fatture/page.tsx:fetch("/api/invoices")❌/src/app/(dashboard)/incassi/movimenti/page.tsx: 15+ fetch senza credentials ❌/src/components/(sidebar)/header.tsx:fetch("/api/auth/logout")❌/src/components/Dashboard/widgets/*.tsx: 10+ fetch senza credentials ❌- E decine di altri file…
Chiamate CORRETTE (solo 3 file):
/src/app/auth/login/page.tsx:fetch(..., { credentials: "include" })✅/src/store/slices/authSlice.ts:fetch(..., { credentials: "include" })✅- E pochissimi altri…
La Soluzione
1. Creato fetchWithAuth wrapper
File: /src/lib/fetchWithAuth.ts
export async function fetchWithAuth(
input: RequestInfo | URL,
init?: FetchOptions,
): Promise<Response> {
const options: FetchOptions = {
...init,
credentials: "include", // SEMPRE
};
const response = await fetch(input, options);
// Auto-redirect al login se 401
if (response.status === 401 && typeof window !== "undefined") {
window.location.href = "/auth/login";
}
return response;
}Helper functions:
fetchGet(url)→ GET con credentialsfetchPost(url, data)→ POST con credentialsfetchPut(url, data)→ PUT con credentialsfetchDelete(url)→ DELETE con credentials
2. Sistemato il middleware
File: /middleware.ts
- Logging per debug
- Auto-refresh token se scade entro 24h
- Usa
response.cookies.set()invece di header manuale
3. Sistemato il login
File: /src/app/api/auth/login/route.ts
- Usa
response.cookies.set()invece diSet-Cookieheader manuale - Più affidabile e corretto
4. Fix immediato applicato
- Header logout ora usa
fetchPost✅ - Tutti gli altri file vanno migrati gradualmente
Come Procedere
Prossimi Step (URGENTE):
-
Migra TUTTE le fetch() a fetchWithAuth() in questi file critici:
/src/app/(dashboard)/incassi/movimenti/page.tsx(15+ fetch)- Tutti i widget della dashboard
- Tutte le pagine delle fatture
- Tutte le pagine dei dipendenti
-
Cerca e sostituisci pattern:
// PRIMA (SBAGLIATO) const response = await fetch("/api/..."); // DOPO (CORRETTO) const response = await fetchWithAuth("/api/...");Oppure usa gli helper:
// GET const response = await fetchGet("/api/..."); // POST const response = await fetchPost("/api/...", { data }); -
Grep search per trovare tutte le fetch sbagliate:
# Cerca tutte le fetch senza credentials grep -r "await fetch(" src/ --include="*.tsx" --include="*.ts"
Testing
Dopo la migrazione, testa:
- Login → dovrebbe funzionare sempre ✅
- Refresh pagina → non dovrebbe buttare fuori ✅
- Navigazione tra pagine → cookie sempre inviato ✅
- Logout → cookie eliminato correttamente ✅
Come verificare nel browser:
- Apri DevTools → Network
- Filtra per
/api/ - Clicca su una richiesta
- Verifica Headers → Request Headers → Cookie: auth-token=… ✅
Perché È Successo
NextJS 13+ con App Router usa cookie-based authentication ma fetch() del browser NON invia cookie automaticamente per sicurezza (per prevenire CSRF).
Serve credentials: "include" SEMPRE quando si fanno chiamate API alla propria app.
Summary
ROOT CAUSE: 90% delle fetch() non includono credentials → cookie non inviato → auth fallisce
FIX: Wrapper fetchWithAuth() che forza credentials: "include" sempre
AZIONE RICHIESTA: Migrare TUTTE le fetch() a fetchWithAuth() o helper functions
File Modificati
- ✅
/src/lib/fetchWithAuth.ts(NUOVO) - ✅
/middleware.ts(logging + refresh token) - ✅
/src/app/api/auth/login/route.ts(cookie corretti) - ✅
/src/components/(sidebar)/header.tsx(logout con fetchPost)
Status: 🟡 Parziale - Serve migrazione massiva di tutte le fetch()