Omfattande guide för att lösa problemet med att cookies inte skickas i Cross-Origin-förfrågningar (CORS)
Om du har stött på ett scenario där servern korrekt anger cookien (synlig i webbläsarens svar), men i efterföljande förfrågningar inte returnerar webbläsaren cookien till servern, är den här guiden för dig. Detta problem uppstår nästan alltid när frontend och backend i ditt projekt finns på två olika domäner eller portar — till exempel frontend på app.example.com och API på api.example.com.
Varför händer detta?
Moderna webbläsare tillämpar två strikta säkerhetspolicyer för att förhindra CSRF-attacker och sessionskapning:
- CORS-policy: Som standard tillåter inte webbläsaren att förfrågningar mellan domäner inkluderar autentiseringsuppgifter (som cookies) om inte servern uttryckligen tillåter detta.
- SameSite-policy: Från och med Chrome 80 behandlas cookies som standard med
SameSite=Lax-beteende, vilket innebär att de inte kommer att skickas i förfrågningar mellan domäner om de inte uttryckligen definieras medSameSite=None.
Den viktiga punkten är att för att lösa detta problem måste både klient- och serversidan konfigureras korrekt. Det räcker inte att bara ändra en sida.
Steg 1: Korrekt serverkonfiguration
Tre gyllene regler på serversidan
Regel 1 — Aktivera autentiseringsuppgifter: Serverns svarshuvud måste innehålla följande värde:
Access-Control-Allow-Credentials: true
Regel 2 — Inga jokertecken: När autentiseringsuppgifter är aktiverade kan du inte använda jokertecknet * i Access-Control-Allow-Origin-huvudet. Du måste ange den exakta fullständiga domänadressen för frontend:
Access-Control-Allow-Origin: https://app.example.com
Regel 3 — Cookie-attribut: Cookien måste ställas in med två attribut: SameSite=None och Secure. Utan dessa två attribut kommer webbläsaren att lagra cookien men aldrig skicka den i förfrågningar mellan domäner.
Exempelkod i Node.js (Express)
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://app.example.com', // Exakt frontend-domän, utan /
credentials: true
}));
app.post('/login', (req, res) => {
res.cookie('session_token', 'abc123', {
httpOnly: true, // Förhindrar JavaScript-åtkomst till cookien
secure: true, // Skickas endast via HTTPS
sameSite: 'none', // Tillåter sändning i Cross-Origin-förfrågningar
maxAge: 24 * 60 * 60 * 1000
});
res.json({ message: 'Inloggning lyckades' });
});
Exempelkod i PHP
<?php
// Ange den exakta frontend-domänen, inte *
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-förfrågan
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
// Ställa in cookien med nödvändiga attribut
setcookie('session_token', 'abc123', [
'expires' => time() + 86400,
'path' => '/',
'secure' => true, // Obligatoriskt
'httponly' => true,
'samesite' => 'None' // Obligatoriskt för Cross-Origin
]);
Notera: Om du använder Laravel, ställ in supports_credentials till true i filen config/cors.php och lägg till frontend-domänen i arrayen allowed_origins.
Steg 2: Korrekt klientkonfiguration (frontend)
Även med fullständig serverkonfiguration kommer webbläsaren fortfarande inte att skicka cookies om du inte uttryckligen förklarar på klientsidan att denna förfrågan är "med autentiseringsuppgifter".
Använda Fetch API
fetch('https://api.example.com/user/profile', {
method: 'GET',
credentials: 'include' // Denna rad är nyckeln till att lösa problemet
})
.then(res => res.json())
.then(data => console.log(data));
Använda Axios
// För en specifik förfrågan
axios.get('https://api.example.com/user/profile', {
withCredentials: true
});
// Eller globalt för hela projektet
axios.defaults.withCredentials = true;
Felsökningschecklista
Om problemet kvarstår efter att ha tillämpat ovanstående, kontrollera dessa punkter i ordning:
- ✅ Är båda sidor på HTTPS? Attributet
Secureinnebär att cookien endast fungerar över krypterade anslutningar. Om din webbplats är på HTTP kommer webbläsaren inte att acceptera cookien. (Undantag: utvecklingsmiljö pålocalhost) - ✅ Är Origin-adressen exakt? Adressen
Access-Control-Allow-Originmåste exakt matcha den URL du ser i webbläsaren. Även en skillnad iwwweller ett avslutande snedstreck/kommer att orsaka misslyckande. - ✅ Är OPTIONS-förfrågan framgångsrik? I fliken Network i webbläsarens utvecklarverktyg, kontrollera Preflight-förfrågan (med OPTIONS-metoden). Denna förfrågan måste besvaras med kod 200 eller 204 och korrekta CORS-huvuden.
- ✅ Är cookien lagrad? I webbläsaren, gå till DevTools ← Application ← Cookies och försäkra dig om att cookien är lagrad med attributen
SecureochSameSite=None. - ✅ Har du en proxy eller mellanliggande brandvägg? Ibland skriver Cloudflare eller webbservrar som Nginx om huvuden. Kontrollera även deras konfiguration.
Sammanfattning
Att skicka cookies i förfrågningar mellan domäner kräver samordning av tre faktorer: servern med Access-Control-Allow-Credentials: true och exakt Origin, cookien med attributen SameSite=None; Secure, och klienten med aktivering av credentials: 'include' eller withCredentials: true. Genom att följa dessa tre punkter kommer problemet att lösas fullständigt.
Pålitlig infrastruktur, sinnesro för utvecklare
Korrekt implementering av CORS och cookiehantering är bara en del av historien; infrastrukturen som ditt projekt körs på spelar också en avgörande roll för tjänstens stabilitet och säkerhet:
Radib Hosting — Höghastighetswebbhotell med fullt stöd för gratis SSL och standardkonfiguration av huvuden; ett idealiskt val för att hosta frontend och backend av dina projekt.
Radib Virtual Server — Om ditt projekt kräver full åtkomst, dedikerade resurser och frihet i webbserverkonfiguration (Nginx/Apache), är Radib virtuella servrar med kraftfull hårdvara och stabilt nätverk det bästa valet för professionella API:er.
Radib Debugging and Security Services — Om du kämpar med komplexa CORS-fel, autentiseringsproblem eller säkerhetsutmaningar, finns Radibs tekniska team, med djup erfarenhet av felsökning och säkring av webbapplikationer, här för att hjälpa dig lösa problemet från roten.


