Omfattende veiledning for å løse problemet med manglende sending av informasjonskapsler i Cross-Origin-forespørsler (CORS)

Hvis du har opplevd et scenario der serveren setter informasjonskapselen riktig (synlig i nettleserens svar), men i påfølgende forespørsler returnerer ikke nettleseren informasjonskapselen til serveren, er denne veiledningen for deg. Dette problemet oppstår nesten alltid når frontend og backend i prosjektet ditt er på to forskjellige domener eller porter — for eksempel frontend på app.example.com og API på api.example.com.

Hvorfor skjer dette?

Moderne nettlesere pålegger to strenge sikkerhetspolicyer for å forhindre CSRF-angrep og øktkapring:

  1. CORS-policy: Som standard tillater ikke nettleseren at forespørsler på tvers av domener inkluderer legitimasjon (som informasjonskapsler) med mindre serveren uttrykkelig tillater dette.
  2. SameSite-policy: Fra Chrome 80 behandles informasjonskapsler som standard med SameSite=Lax-atferd, noe som betyr at de ikke vil bli sendt i forespørsler på tvers av domener med mindre de er eksplisitt definert med SameSite=None.

Det viktige poenget er at for å løse dette problemet, må både klient- og serversiden konfigureres riktig. Det er ikke nok å bare endre den ene siden.

Trinn 1: Riktig serverkonfigurasjon

Tre gyldne regler på serversiden

Regel 1 — Aktiver legitimasjon: Serverens svaroverskrift må inneholde følgende verdi:

Access-Control-Allow-Credentials: true

Regel 2 — Ingen jokertegn: Når legitimasjon er aktivert, kan du ikke bruke *-jokertegnet i Access-Control-Allow-Origin-overskriften. Du må angi den nøyaktige fulle domeneadressen til frontend:

Access-Control-Allow-Origin: https://app.example.com

Regel 3 — Informasjonskapsel-attributter: Informasjonskapselen må settes med to attributter: SameSite=None og Secure. Uten disse to attributtene vil nettleseren lagre informasjonskapselen, men aldri sende den i forespørsler på tvers av domener.

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øyaktig frontend-domene, uten /
  credentials: true
}));

app.post('/login', (req, res) => {
  res.cookie('session_token', 'abc123', {
    httpOnly: true,   // Forhindrer JavaScript-tilgang til informasjonskapselen
    secure: true,     // Sendes bare over HTTPS
    sameSite: 'none', // Tillater sending i Cross-Origin-forespørsler
    maxAge: 24 * 60 * 60 * 1000
  });
  res.json({ message: 'Innlogging vellykket' });
});

Eksempelkode i PHP

<?php
// Angi det nøyaktige frontend-domenet, 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-forespørsel
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

// Sette informasjonskapselen med nødvendige attributter
setcookie('session_token', 'abc123', [
    'expires'  => time() + 86400,
    'path'     => '/',
    'secure'   => true,      // Påkrevet
    'httponly' => true,
    'samesite' => 'None'     // Påkrevet for Cross-Origin
]);

Merk: Hvis du bruker Laravel, sett supports_credentials til true i filen config/cors.php og legg til frontend-domenet i allowed_origins-arrayet.

Trinn 2: Riktig klientkonfigurasjon (frontend)

Selv med fullstendig serverkonfigurasjon vil nettleseren fortsatt ikke sende informasjonskapsler med mindre du på klientsiden uttrykkelig erklærer at denne forespørselen er "med legitimasjon".

Bruke Fetch API

fetch('https://api.example.com/user/profile', {
  method: 'GET',
  credentials: 'include'  // Denne linjen er nøkkelen til å løse problemet
})
  .then(res => res.json())
  .then(data => console.log(data));

Bruke Axios

// For en spesifikk forespørsel
axios.get('https://api.example.com/user/profile', {
  withCredentials: true
});

// Eller globalt for hele prosjektet
axios.defaults.withCredentials = true;

Feilsøkingssjekkliste

Hvis problemet vedvarer etter å ha brukt det ovennevnte, sjekk disse elementene i rekkefølge:

  • Er begge sider på HTTPS? Secure-attributtet betyr at informasjonskapselen bare fungerer over krypterte tilkoblinger. Hvis nettstedet ditt er på HTTP, vil ikke nettleseren akseptere informasjonskapselen. (Unntak: utviklingsmiljø på localhost)
  • Er Origin-adressen nøyaktig? Access-Control-Allow-Origin-adressen må nøyaktig matche URL-en du ser i nettleseren. Selv en forskjell i www eller en avsluttende skråstrek / vil forårsake feil.
  • Er OPTIONS-forespørselen vellykket? I Network-fanen i nettleserens utviklerverktøy, sjekk Preflight-forespørselen (med OPTIONS-metoden). Denne forespørselen må besvares med kode 200 eller 204 og korrekte CORS-overskrifter.
  • Er informasjonskapselen lagret? I nettleseren, gå til DevTools ← Application ← Cookies og forsikre deg om at informasjonskapselen er lagret med attributtene Secure og SameSite=None.
  • Har du en proxy eller mellomliggende brannmur? Noen ganger omskriver Cloudflare eller webservere som Nginx overskrifter. Sjekk også deres konfigurasjon.

Oppsummering

Sending av informasjonskapsler i forespørsler på tvers av domener krever koordinering av tre faktorer: serveren med Access-Control-Allow-Credentials: true og nøyaktig Origin, informasjonskapselen med attributtene SameSite=None; Secure, og klienten med aktivering av credentials: 'include' eller withCredentials: true. Ved å følge disse tre punktene vil problemet bli fullstendig løst.


Pålitelig infrastruktur, ro i sinnet for utviklere

Riktig implementering av CORS og informasjonskapselhåndtering er bare en del av historien; infrastrukturen som prosjektet ditt kjører på spiller også en avgjørende rolle for stabiliteten og sikkerheten til tjenesten:

Radib Hosting — Rask webhotell med full støtte for gratis SSL og standard overskriftskonfigurasjon; et ideelt valg for å hoste frontend og backend av prosjektene dine.

Radib Virtual Server — Hvis prosjektet ditt krever full tilgang, dedikerte ressurser og frihet i webserverkonfigurasjon (Nginx/Apache), er Radib virtuelle servere med kraftig maskinvare og stabilt nettverk det beste valget for profesjonelle API-er.

Radib Debugging and Security Services — Hvis du sliter med komplekse CORS-feil, autentiseringsproblemer eller sikkerhetsutfordringer, er Radibs tekniske team, med dyp erfaring i feilsøking og sikring av webapplikasjoner, her for å hjelpe deg med å løse problemet fra roten.

 

Var dette svaret til hjelp? 112 brukere syntes dette svaret var til hjelp (112 Stemmer)