🔥 FIX DEFINITIVO: Login Produzione
🎯 TUTTI I PROBLEMI RISOLTI
Problema #1: Cookie SameSite=“strict” (RISOLTO ✅)
Issue: Con sameSite: "strict", il cookie non veniva inviato nei redirect.
Fix:
// File: src/app/api/auth/login/route.ts
response.cookies.set("auth-token", token, {
httpOnly: true,
secure: isProduction,
sameSite: "lax", // ✅ CAMBIATO da "strict"
maxAge: 60 * 60 * 24 * 7,
path: "/",
});Problema #2: Race Condition + Cookie Timing (RISOLTO ✅)
Issue: Il redirect avveniva troppo velocemente, prima che il browser processasse il cookie.
Cosa succedeva:
- Login API imposta il cookie
router.push("/")redirect immediato- Middleware della homepage controlla il cookie → NON TROVATO!
- Middleware reindirizza al login → LOOP INFINITO o 401
Fix:
// File: src/app/auth/login/page.tsx
toast.success("Login effettuato con successo!");
// Piccolo delay per il cookie + full page reload
await new Promise(resolve => setTimeout(resolve, 100));
window.location.href = "/";Perché window.location.href invece di router.push()?
- ✅ Forza un full page reload
- ✅ Assicura che tutti i cookie siano caricati
- ✅ Il middleware può verificare correttamente il cookie
- ✅ AuthProvider carica i dati freschi
- ✅ Previene race conditions
Problema #3: Doppio fetchCurrentUser (RISOLTO ✅)
Issue: Due chiamate fetchCurrentUser() in conflitto:
- Una nella pagina login prima del redirect
- Una nell’AuthProvider dopo il redirect
Fix: Rimosso il fetchCurrentUser() dalla pagina login. Ora:
- Login imposta il cookie
- Redirect con
window.location.href - AuthProvider carica automaticamente i dati
📝 Codice Finale
/src/app/auth/login/page.tsx
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
const response = await fetch("/api/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include",
body: JSON.stringify({ email, password }),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || "Errore durante il login");
}
toast.success("Login effettuato con successo!");
// Delay per cookie + full page reload
await new Promise(resolve => setTimeout(resolve, 100));
window.location.href = "/";
} catch (error) {
toast.error(
error instanceof Error ? error.message : "Errore durante il login",
);
} finally {
setIsLoading(false);
}
};/src/app/api/auth/login/route.ts
// Imposta cookie httpOnly
const isProduction = process.env.NODE_ENV === "production";
response.cookies.set("auth-token", token, {
httpOnly: true,
secure: isProduction,
sameSite: "lax",
maxAge: 60 * 60 * 24 * 7,
path: "/",
});
// Previeni caching
response.headers.set("Cache-Control", "no-store, no-cache, must-revalidate");🧪 Test Completo
1. Testa in Locale
# Imposta NODE_ENV=production temporaneamente
NODE_ENV=production npm run dev
# Prova login
# Verifica che funzioni2. Deploy in Produzione
git add .
git commit -m "fix: login production issues - cookie sameSite + timing"
git push
# Deploy3. Verifica nei Log
Dopo il login, dovresti vedere:
[LOGIN] Attempting login for: user@example.com
[LOGIN] Login successful for user: 507f...
[LOGIN] Cookie set successfully
[LOGIN] - isProduction: true
[LOGIN] - secure: true
[LOGIN] - sameSite: lax
# Dopo il redirect
[AUTH/ME] All cookies: auth-token
[AUTH/ME] auth-token present: true
[AUTH/ME] Token decoded successfully for user: 507f...
[AUTH/ME] User data fetched successfully4. Verifica nel Browser
DevTools > Application > Cookies
Cookie auth-token deve avere:
- ✅ HttpOnly: ✓
- ✅ Secure: ✓ (in HTTPS)
- ✅ SameSite: Lax
- ✅ Path:
/ - ✅ Expires: 7 giorni
DevTools > Network
Sequenza richieste:
- ✅ POST
/api/auth/login→ 200, Set-Cookie presente - ✅ Delay 100ms
- ✅ Full page reload
/ - ✅ GET
/api/auth/me→ 200, Cookie inviato
🎓 Lezioni Apprese
SameSite Cookie Policy
- ❌
strict: Troppo restrittivo, blocca anche redirect interni - ✅
lax: Perfetto per autenticazione, permette navigazioni GET - ⚠️
none: Solo per cross-domain, richiedesecure: true
Timing Issues
I cookie HTTP non sono disponibili immediatamente in JavaScript:
- Il browser deve processare l’header
Set-Cookie - Serve un piccolo delay prima del redirect
- O meglio ancora, usare
window.location.hrefper un full reload
Client vs Server Navigation
router.push(): Client-side navigation, veloce ma può avere timing issueswindow.location.href: Full page reload, più lento ma più affidabile per login
Race Conditions
Evitare chiamate duplicate:
- ❌
fetchCurrentUser()nella pagina login + AuthProvider - ✅ Solo AuthProvider gestisce il fetching
📚 Riferimenti
TLDR: Cambiato sameSite: "strict" → "lax" + aggiunto delay 100ms + usato window.location.href per full reload.
Last updated on