Omfattende guide til at løse problemet med manglende afsendelse af cookies i cross-origin-anmodninger (CORS)
Hvis du har oplevet et scenarie, hvor serveren angiver cookien korrekt (synlig i browserens svar), men i efterfølgende anmodninger returnerer browseren ikke cookien til serveren, er denne guide til dig. Dette problem opstår næsten altid, når frontend og backend i dit projekt er på to forskellige domæner eller porte — f.eks. frontend på app.example.com og API på api.example.com.
Hvorfor sker dette?
Moderne browsere pålægger to strenge sikkerhedspolitikker for at forhindre CSRF-angreb og sessionskapring:
- CORS-politik: Som standard tillader browseren ikke, at anmodninger mellem domæner indeholder legitimationsoplysninger (som cookies), medmindre serveren udtrykkeligt tillader dette.
- SameSite-politik: Fra Chrome 80 behandles cookies som standard med
SameSite=Lax-adfærd, hvilket betyder, at de ikke vil blive sendt i anmodninger mellem domæner, medmindre de udtrykkeligt er defineret medSameSite=None.
Det vigtige punkt er, at for at løse dette problem skal både klient- og serversiden konfigureres korrekt. Det er ikke nok kun at ændre den ene side.
Trin 1: Korrekt serverkonfiguration
Tre gyldne regler på serversiden
Regel 1 — Aktivering af legitimationsoplysninger: Serverens svarhoved skal indeholde følgende værdi:
Access-Control-Allow-Credentials: true
Regel 2 — Ingen jokertegn: Når legitimationsoplysninger er aktiveret, kan du ikke bruge * jokertegnet i Access-Control-Allow-Origin-headeren. Du skal angive den nøjagtige fulde domæneadresse for frontend:
Access-Control-Allow-Origin: https://app.example.com
Regel 3 — Cookie-attributter: Cookien skal angives med to attributter: SameSite=None og Secure. Uden disse to attributter vil browseren gemme cookien, men aldrig sende den i anmodninger mellem domæner.
Eksempelkode i Node.js (Express)
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://app.example.com', // Nøjagtig frontend-domæne, uden /
credentials: true
}));
app.post('/login', (req, res) => {
res.cookie('session_token', 'abc123', {
httpOnly: true, // Forhindrer JavaScript-adgang til cookien
secure: true, // Sendes kun over HTTPS
sameSite: 'none', // Tillader afsendelse i Cross-Origin-anmodninger
maxAge: 24 * 60 * 60 * 1000
});
res.json({ message: 'Login lykkedes' });
});
Eksempelkode i PHP
<?php
// Angiv det nøjagtige frontend-domæne, ikke *
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");
// Svar på Preflight-anmodning
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
// Indstilling af cookien med de nødvendige attributter
setcookie('session_token', 'abc123', [
'expires' => time() + 86400,
'path' => '/',
'secure' => true, // Påkrævet
'httponly' => true,
'samesite' => 'None' // Påkrævet for Cross-Origin
]);
Bemærk: Hvis du bruger Laravel, skal du indstille supports_credentials til true i filen config/cors.php og tilføje frontend-domænet til arrayet allowed_origins.
Trin 2: Korrekt klientkonfiguration (frontend)
Selv med fuldstændig serverkonfiguration vil browseren stadig ikke sende cookies, medmindre du udtrykkeligt erklærer på klientsiden, at denne anmodning er "med legitimationsoplysninger".
Brug af Fetch API
fetch('https://api.example.com/user/profile', {
method: 'GET',
credentials: 'include' // Denne linje er nøglen til at løse problemet
})
.then(res => res.json())
.then(data => console.log(data));
Brug af Axios
// For en specifik anmodning
axios.get('https://api.example.com/user/profile', {
withCredentials: true
});
// Eller globalt for hele projektet
axios.defaults.withCredentials = true;
Fejlfindings-tjekliste
Hvis problemet fortsætter efter anvendelse af ovenstående, skal du kontrollere disse punkter i rækkefølge:
- ✅ Er begge sider på HTTPS? Attributten
Securebetyder, at cookien kun fungerer over krypterede forbindelser. Hvis dit site er på HTTP, accepterer browseren ikke cookien. (Undtagelse: udviklingsmiljø pålocalhost) - ✅ Er Origin-adressen nøjagtig? Adressen
Access-Control-Allow-Originskal nøjagtigt matche den URL, du ser i browseren. Selv en forskel iwwweller en afsluttende skråstreg/vil medføre fejl. - ✅ Er OPTIONS-anmodningen vellykket? I fanen Network i browserens udviklingsværktøjer skal du kontrollere Preflight-anmodningen (med OPTIONS-metoden). Denne anmodning skal besvares med kode 200 eller 204 og korrekte CORS-headere.
- ✅ Er cookien gemt? I browseren skal du gå til DevTools ← Application ← Cookies og sikre dig, at cookien er gemt med attributterne
SecureogSameSite=None. - ✅ Har du en proxy eller mellemliggende firewall? Nogle gange omskriver Cloudflare eller webservere som Nginx headere. Kontroller også deres konfiguration.
Opsummering
Afsendelse af cookies i anmodninger mellem domæner kræver koordinering af tre faktorer: serveren med Access-Control-Allow-Credentials: true og nøjagtig Origin, cookien med attributterne SameSite=None; Secure og klienten med aktivering af credentials: 'include' eller withCredentials: true. Ved at følge disse tre punkter vil problemet blive fuldstændigt løst.
Pålidelig infrastruktur, ro i sindet for udviklere
Korrekt implementering af CORS og cookie-håndtering er kun en del af historien; den infrastruktur, som dit projekt kører på, spiller også en afgørende rolle for stabiliteten og sikkerheden af tjenesten:
Radib Hosting — Højhastigheds webhosting med fuld support til gratis SSL og standard header-konfiguration; et ideelt valg til hosting af frontend og backend af dine projekter.
Radib Virtual Server — Hvis dit projekt kræver fuld adgang, dedikerede ressourcer og frihed i web-serverkonfiguration (Nginx/Apache), er Radib virtuelle servere med kraftfuld hardware og stabilt netværk det bedste valg til professionelle API'er.
Radib Debugging og Security Services — Hvis du kæmper med komplekse CORS-fejl, autentificeringsproblemer eller sikkerhedsudfordringer, er Radibs tekniske team, med dyb erfaring i fejlfinding og sikring af webapplikationer, her for at hjælpe dig med at løse problemet fra roden.


