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:

  1. CORS-politik: Som standard tillader browseren ikke, at anmodninger mellem domæner indeholder legitimationsoplysninger (som cookies), medmindre serveren udtrykkeligt tillader dette.
  2. 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 med SameSite=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 Secure betyder, 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-Origin skal nøjagtigt matche den URL, du ser i browseren. Selv en forskel i www eller 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 Secure og SameSite=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.

 

Hjalp dette svar dig? 112 Kunder som kunne bruge dette svar (112 Stem)