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:
- CORS-i poliitika: Vaikimisi ei luba brauser ristpäringutel kaasata mandaate (nagu küpsiseid), välja arvatud juhul, kui server seda selgesõnaliselt lubab.
- 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äärtusegaSameSite=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
Securetä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 aadressillocalhost) - ✅ Kas Origin-aadress on täpne? Aadress
Access-Control-Allow-Originpeab täpselt ühtima URL-iga, mida brauseris näete. Isegi erinevuswww-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
SecurejaSameSite=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.


