Skip to Content
TecnicaAutenticazione🔥 FIX DEFINITIVO: Login Produzione

🔥 FIX DEFINITIVO: Login Produzione

🎯 TUTTI I PROBLEMI RISOLTI

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: "/", });

Issue: Il redirect avveniva troppo velocemente, prima che il browser processasse il cookie.

Cosa succedeva:

  1. Login API imposta il cookie
  2. router.push("/") redirect immediato
  3. Middleware della homepage controlla il cookie → NON TROVATO!
  4. 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:

  1. Login imposta il cookie
  2. Redirect con window.location.href
  3. 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 funzioni

2. Deploy in Produzione

git add . git commit -m "fix: login production issues - cookie sameSite + timing" git push # Deploy

3. 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 successfully

4. 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:

  1. ✅ POST /api/auth/login → 200, Set-Cookie presente
  2. ✅ Delay 100ms
  3. ✅ Full page reload /
  4. ✅ GET /api/auth/me → 200, Cookie inviato

🎓 Lezioni Apprese

  • strict: Troppo restrittivo, blocca anche redirect interni
  • lax: Perfetto per autenticazione, permette navigazioni GET
  • ⚠️ none: Solo per cross-domain, richiede secure: 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.href per un full reload

Client vs Server Navigation

  • router.push(): Client-side navigation, veloce ma può avere timing issues
  • window.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