Guida completa per risolvere il problema dell'invio dei cookie nelle richieste Cross-Origin (CORS)
Se ti sei trovato in uno scenario in cui il server imposta correttamente il cookie (visibile nella risposta del browser), ma nelle richieste successive il browser non restituisce quel cookie al server, questa guida fa per te. Questo problema si verifica quasi sempre quando il frontend e il backend del tuo progetto si trovano su due domini o porte diverse — ad esempio, il frontend su app.example.com e l'API su api.example.com.
Perché succede?
I browser moderni impongono due rigide politiche di sicurezza per prevenire attacchi CSRF e il dirottamento delle sessioni:
- Politica CORS: Per impostazione predefinita, il browser non consente alle richieste tra domini di includere credenziali (come i cookie) a meno che il server non lo permetta esplicitamente.
- Politica SameSite: A partire da Chrome 80, i cookie vengono trattati per impostazione predefinita con il comportamento
SameSite=Lax, il che significa che non verranno inviati in richieste tra domini a meno che non siano esplicitamente definiti conSameSite=None.
Il punto importante è che per risolvere questo problema, sia il lato client che il lato server devono essere configurati correttamente. Modificare solo un lato non è sufficiente.
Passo 1: Configurazione corretta del server
Tre regole d'oro sul lato server
Regola 1 — Abilitare le credenziali: L'intestazione di risposta del server deve includere il seguente valore:
Access-Control-Allow-Credentials: true
Regola 2 — Nessun carattere jolly: Quando le credenziali sono abilitate, non è possibile utilizzare il carattere jolly * nell'intestazione Access-Control-Allow-Origin. È necessario specificare esattamente l'indirizzo di dominio completo del frontend:
Access-Control-Allow-Origin: https://app.example.com
Regola 3 — Attributi del cookie: Il cookie deve essere impostato con due attributi: SameSite=None e Secure. Senza questi due attributi, il browser memorizzerà il cookie ma non lo invierà mai in richieste tra domini.
Codice di esempio in Node.js (Express)
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://app.example.com', // Dominio esatto del frontend, senza /
credentials: true
}));
app.post('/login', (req, res) => {
res.cookie('session_token', 'abc123', {
httpOnly: true, // Impedisce l'accesso JavaScript al cookie
secure: true, // Inviato solo tramite HTTPS
sameSite: 'none', // Consente l'invio in richieste Cross-Origin
maxAge: 24 * 60 * 60 * 1000
});
res.json({ message: 'Accesso riuscito' });
});
Codice di esempio in PHP
<?php
// Specifica il dominio esatto del frontend, non *
header("Access-Control-Allow-Origin: https://app.example.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
// Rispondere alla richiesta Preflight
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
// Impostare il cookie con gli attributi richiesti
setcookie('session_token', 'abc123', [
'expires' => time() + 86400,
'path' => '/',
'secure' => true, // Richiesto
'httponly' => true,
'samesite' => 'None' // Richiesto per Cross-Origin
]);
Nota: Se stai utilizzando Laravel, imposta supports_credentials su true nel file config/cors.php e aggiungi il dominio del frontend all'array allowed_origins.
Passo 2: Configurazione corretta del client (frontend)
Anche con una configurazione completa del server, il browser non invierà comunque i cookie a meno che non si dichiari esplicitamente sul lato client che questa richiesta è "con credenziali".
Utilizzo di Fetch API
fetch('https://api.example.com/user/profile', {
method: 'GET',
credentials: 'include' // Questa riga è la chiave per risolvere il problema
})
.then(res => res.json())
.then(data => console.log(data));
Utilizzo di Axios
// Per una richiesta specifica
axios.get('https://api.example.com/user/profile', {
withCredentials: true
});
// O globalmente per l'intero progetto
axios.defaults.withCredentials = true;
Lista di controllo per la risoluzione dei problemi
Se il problema persiste dopo aver applicato quanto sopra, verifica questi elementi in ordine:
- ✅ Entrambi i lati sono su HTTPS? L'attributo
Securesignifica che il cookie funziona solo su connessioni crittografate. Se il tuo sito è su HTTP, il browser non accetterà il cookie. (Eccezione: ambiente di sviluppo sulocalhost) - ✅ L'indirizzo Origin è esatto? L'indirizzo
Access-Control-Allow-Origindeve corrispondere esattamente all'URL che vedi nel browser. Anche una differenza inwwwo uno slash finale/causerà un errore. - ✅ La richiesta OPTIONS ha successo? Nella scheda Network degli strumenti di sviluppo del browser, controlla la richiesta Preflight (con il metodo OPTIONS). Questa richiesta deve essere risposta con il codice 200 o 204 e le intestazioni CORS corrette.
- ✅ Il cookie è memorizzato? Nel browser, vai su DevTools ← Application ← Cookies e assicurati che il cookie sia memorizzato con gli attributi
SecureeSameSite=None. - ✅ Hai un proxy o un firewall intermedio? A volte Cloudflare o server web come Nginx riscrivono le intestazioni. Controlla anche la loro configurazione.
Riepilogo
L'invio di cookie in richieste tra domini richiede il coordinamento di tre fattori: il server con Access-Control-Allow-Credentials: true e Origin esatto, il cookie con attributi SameSite=None; Secure, e il client con l'attivazione di credentials: 'include' o withCredentials: true. Seguendo questi tre punti, il problema verrà completamente risolto.
Infrastruttura affidabile, tranquillità per gli sviluppatori
L'implementazione corretta di CORS e la gestione dei cookie è solo una parte della storia; l'infrastruttura su cui gira il tuo progetto gioca anche un ruolo decisivo nella stabilità e sicurezza del servizio:
Radib Hosting — Hosting web ad alta velocità con supporto completo per SSL gratuito e configurazione standard delle intestazioni; una scelta ideale per ospitare il frontend e il backend dei tuoi progetti.
Radib Virtual Server — Se il tuo progetto richiede accesso completo, risorse dedicate e libertà nella configurazione del server web (Nginx/Apache), i server virtuali Radib con hardware potente e rete stabile sono la scelta migliore per API professionali.
Radib Debugging and Security Services — Se hai a che fare con errori CORS complessi, problemi di autenticazione o sfide di sicurezza, il team tecnico di Radib, con una profonda esperienza nella risoluzione dei problemi e nella sicurezza delle applicazioni web, è qui per aiutarti a risolvere il problema alla radice.


