Cause più comuni per req.cookies === undefined in Express:

  1. Middleware mancante/nel posto sbagliato.
  2. Serve cookie-parser prima delle route che leggono i cookie.
import express from 'express';
import cookieParser from 'cookie-parser';

const app = express();
app.use(cookieParser());           // ⬅️ prima di qualunque router
// ...le tue route
  1. Senza di questo req.cookies non viene popolato.
  2. Secure su HTTP (sviluppo).
  3. Con secure: true il browser non invia il cookie su richieste non-HTTPS. In locale, se usi http://localhost o http://127.0.0.1, il cookie viene ignorato. In dev usa:
res.cookie(COOKIE_CODE_VERIFIER, codeVerifierCookieString, {
  httpOnly: true,
  sameSite: 'lax',                 // None è necessario solo per contesti cross-site
  secure: process.env.NODE_ENV === 'production',
  path: '/',                       // vedi punto 3
});
  1. Path/host non corrispondenti.
  2. Se non specifichi path, il default è la cartella della URL che ha impostato il cookie (es. da /auth/startpath=/auth). Poi chiamando /api/... il cookie non viene inviato. Imposta sempre path: '/'.
  3. Inoltre localhost127.0.0.1 e app.example.comexample.com per i cookie: devono combaciare host (o usa domain adatto).
  4. Cross-origin senza credenziali.
  5. Se il client chiama un altro origin (porta diversa inclusa), servono credenziali esplicite:
fetch('https://api.example.test/route', {
  method: 'POST',
  credentials: 'include',
  // con axios: { withCredentials: true }
});
import cors from 'cors';
app.use(cors({
  origin: 'https://app.example.test', // niente '*'
  credentials: true,
}));
  1. In contesti cross-site moderni, SameSite: 'none' è obbligatorio e secure: true. Se non sei realmente cross-site, preferisci lax.
  2. Cookie non ancora inviato dal client.
  3. Il cookie impostato in una risposta è disponibile solo dalle richieste successive del client.
  4. Nome/valore o dimensioni.
  5. Nome diverso tra set e get, valore undefined/null, o header Set-Cookie scartato perché troppo grande (limite per dominio).

Diagnostica rapida:

console.log('Raw Cookie header:', req.headers.cookie);
console.log('Parsed cookies:', req.cookies);

Nota: HttpOnly non influisce lato server; impedisce solo l’accesso via document.cookie.

Curiosità collegata: i browser stanno limitando i cookie di terza parte; se devi davvero operare in contesto cross-site valuta i cookie partizionati (“Partitioned/CHIPS”), che permettono l’uso isolato per origin, evitando i blocchi dei third-party cookie.