Põhjalik juhend küpsiste ristpäringutes (CORS) saatmata jätmise probleemi lahendamiseks

Kui olete kokku puutunud stsenaariumiga, kus server määrab küpsise õigesti (brauseri vastuses nähtav), kuid järgnevates päringutes brauser seda küpsist serverile tagasi ei saada, on see juhend teile. See probleem ilmneb peaaegu alati siis, kui teie projekti esi- ja tagaots on kahel erineval domeenil või pordil — näiteks esiosa aadressil app.example.com ja API aadressil api.example.com.

Miks see juhtub?

Kaasaegsed brauserid rakendavad kahte ranget turvapoliitikat, et vältida CSRF-ründeid ja seansi kaaperdamist:

  1. CORS-i poliitika: Vaikimisi ei luba brauser ristpäringutel kaasata mandaate (nagu küpsiseid), välja arvatud juhul, kui server seda selgesõnaliselt lubab.
  2. SameSite'i poliitika: Alates Chrome 80-st käsitletakse küpsiseid vaikimisi käitumisega SameSite=Lax, mis tähendab, et neid ei saadeta ristpäringutes, välja arvatud juhul, kui need on selgesõnaliselt määratletud väärtusega SameSite=None.

Oluline punkt on see, et selle probleemi lahendamiseks peavad nii kliendi- kui ka serveripool olema õigesti konfigureeritud. Ainult ühe poole muutmisest ei piisa.

1. samm: Õige serveri konfiguratsioon

Kolm kuldpäringut serveripoolses konfigureerimises

1. reegel — Mandaatide lubamine: Serveri vastuspäis peab sisaldama järgmist väärtust:

Access-Control-Allow-Credentials: true

2. reegel — Meta-märkide mittekasutamine: Kui mandaadid on lubatud, ei saa te päises Access-Control-Allow-Origin kasutada meta-märki *. Peate täpselt määrama esiosa täieliku domeeniaadressi:

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

3. reegel — Küpsise atribuudid: Küpsis tuleb määrata kahe atribuudiga: SameSite=None ja Secure. Ilma nende kahe atribuudita salvestab brauser küpsise, kuid ei saada seda kunagi ristpäringutes.

Näidiskood Node.js-is (Express)

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors({
  origin: 'https://app.example.com', // Täpne esiosa domeen, ilma lõpu /
  credentials: true
}));

app.post('/login', (req, res) => {
  res.cookie('session_token', 'abc123', {
    httpOnly: true,   // Takistab JavaScripti juurdepääsu küpsisele
    secure: true,     // Saadetakse ainult HTTPS-i kaudu
    sameSite: 'none', // Lubab saatmist ristpäringutes
    maxAge: 24 * 60 * 60 * 1000
  });
  res.json({ message: 'Sisselogimine õnnestus' });
});

Näidiskood PHP-s

<?php
// Määrake täpne esiosa domeen, mitte *
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");

// Vastus eelpäringule (Preflight)
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(204);
    exit;
}

// Küpsise määramine vajalike atribuutidega
setcookie('session_token', 'abc123', [
    'expires'  => time() + 86400,
    'path'     => '/',
    'secure'   => true,      // Nõutud
    'httponly' => true,
    'samesite' => 'None'     // Nõutud ristpäringute jaoks
]);

Märkus: Kui kasutate Laravelit, määrake failis config/cors.php väärtus supports_credentials väärtusele true ja lisage esiosa domeen massiivi allowed_origins.

2. samm: Õige kliendi (esiosa) konfiguratsioon

Isegi täieliku serveri konfiguratsiooni korral ei saada brauser küpsiseid, kui te kliendipoolses osas selgesõnaliselt ei deklareeri, et see päring on "mandaatidega".

Fetch API kasutamine

fetch('https://api.example.com/user/profile', {
  method: 'GET',
  credentials: 'include'  // See rida on probleemi lahendamise võti
})
  .then(res => res.json())
  .then(data => console.log(data));

Axiosi kasutamine

// Konkreetse päringu jaoks
axios.get('https://api.example.com/user/profile', {
  withCredentials: true
});

// Või globaalselt kogu projekti jaoks
axios.defaults.withCredentials = true;

Tõrkeotsingu kontrollnimekiri

Kui pärast ülaltoodu rakendamist probleem püsib, kontrollige neid üksusi järjekorras:

  • Kas mõlemad pooled on HTTPS-is? Atribuut Secure tähendab, et küpsis töötab ainult krüptitud ühenduste kaudu. Kui teie sait on HTTP-s, ei võta brauser küpsist vastu. (Erand: arenduskeskkond aadressil localhost)
  • Kas Origin-aadress on täpne? Aadress Access-Control-Allow-Origin peab täpselt ühtima URL-iga, mida brauseris näete. Isegi erinevus www-s või lõpus olev kaldkriips / põhjustab ebaõnnestumist.
  • Kas OPTIONS-päring on edukas? Brauseri arendustööriistade vahekaardil Network kontrollige eelpäringut (OPTIONS-meetodiga). Sellele päringule tuleb vastata koodiga 200 või 204 ja õigete CORS-päistega.
  • Kas küpsis on salvestatud? Brauseris minge jaotisse DevTools ← Application ← Cookies ja veenduge, et küpsis on salvestatud atribuutidega Secure ja SameSite=None.
  • Kas teil on vahendusserver või vahepealne tulemüür? Mõnikord kirjutavad Cloudflare või veebiserverid nagu Nginx päised ümber. Kontrollige ka nende konfiguratsiooni.

Kokkuvõte

Küpsiste saatmine ristpäringutes nõuab kolme teguri koordineerimist: server koos Access-Control-Allow-Credentials: true ja täpse Originiga, küpsis atribuutidega SameSite=None; Secure ja klient aktiveeritud credentials: 'include' või withCredentials: true-ga. Neid kolme punkti järgides lahendatakse probleem täielikult.


Usaldusväärne infrastruktuur, arendajatele meelerahu

CORS-i õige rakendamine ja küpsiste haldamine on vaid osa loost; infrastruktuur, millel teie projekt töötab, mängib samuti otsustavat rolli teenuse stabiilsuses ja turvalisuses:

Radib Hosting — Kiire veebimajutus täieliku tasuta SSL-i ja standardpäiste konfiguratsiooniga; ideaalne valik teie projektide esi- ja tagaotsa majutamiseks.

Radib Virtual Server — Kui teie projekt nõuab täielikku juurdepääsu, spetsiaalseid ressursse ja vabadust veebiserveri konfiguratsioonis (Nginx/Apache), on Radib virtuaalserverid võimsa riistvara ja stabiilse võrguga parim valik professionaalsete API-de jaoks.

Radib silumis- ja turbeteenused — Kui tegelete keerukate CORS-vigade, autentimisprobleemide või turvaprobleemidega, on Radibi tehniline meeskond, kellel on sügav kogemus veebirakenduste tõrkeotsingul ja turvamisel, teie kõrval, et aidata teil probleemi juurtest lahendada.

 

Kas see vastus oli kasulik? 112 Kasutajad peavad seda kasulikuks (112 Hääled)