Sveobuhvatni vodič za rješavanje problema slanja kolačića u zahtjevima između različitih domena (CORS)
Ako ste se susreli sa scenarijem u kojem poslužitelj ispravno postavlja kolačić (vidljiv u odgovoru preglednika), ali u kasnijim zahtjevima preglednik ne vraća taj kolačić poslužitelju, ovaj vodič je za vas. Ovaj se problem gotovo uvijek događa kada su prednji i stražnji dio vašeg projekta na dvije različite domene ili porta — na primjer, prednji dio na app.example.com, a API na api.example.com.
Zašto se to događa?
Moderni preglednici nameću dvije stroge sigurnosne politike kako bi spriječili CSRF napade i krađu sesija:
- CORS pravilo: Prema zadanim postavkama, preglednik ne dopušta zahtjevima između domena da uključuju vjerodajnice (poput kolačića) osim ako poslužitelj to izričito ne dopusti.
- SameSite pravilo: Od Chrome 80 nadalje, kolačići se prema zadanim postavkama tretiraju s ponašanjem
SameSite=Lax, što znači da se neće slati u zahtjevima između domena osim ako su izričito definirani sSameSite=None.
Važno je napomenuti da se za rješavanje ovog problema i klijentska i poslužiteljska strana moraju ispravno konfigurirati. Samo modificiranje jedne strane nije dovoljno.
Korak 1: Ispravna konfiguracija poslužitelja
Tri zlatna pravila na poslužiteljskoj strani
Pravilo 1 — Omogućite vjerodajnice: Zaglavlje odgovora poslužitelja mora sadržavati sljedeću vrijednost:
Access-Control-Allow-Credentials: true
Pravilo 2 — Bez zamjenskih znakova: Kada su vjerodajnice omogućene, ne možete koristiti * zamjenski znak u zaglavlju Access-Control-Allow-Origin. Morate točno navesti punu adresu domene prednjeg dijela:
Access-Control-Allow-Origin: https://app.example.com
Pravilo 3 — Atributi kolačića: Kolačić se mora postaviti s dva atributa: SameSite=None i Secure. Bez ova dva atributa, preglednik će pohraniti kolačić, ali ga nikada neće poslati u zahtjevima između domena.
Primjer koda u Node.js (Express)
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://app.example.com', // Točna domena prednjeg dijela, bez /
credentials: true
}));
app.post('/login', (req, res) => {
res.cookie('session_token', 'abc123', {
httpOnly: true, // Sprječava pristup kolačiću putem JavaScripta
secure: true, // Šalje se samo putem HTTPS-a
sameSite: 'none', // Omogućuje slanje u zahtjevima između domena
maxAge: 24 * 60 * 60 * 1000
});
res.json({ message: 'Prijava uspješna' });
});
Primjer koda u PHP-u
<?php
// Navedite točnu domenu prednjeg dijela, ne *
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");
// Odgovor na Preflight zahtjev
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(204);
exit;
}
// Postavljanje kolačića s potrebnim atributima
setcookie('session_token', 'abc123', [
'expires' => time() + 86400,
'path' => '/',
'secure' => true, // Obavezno
'httponly' => true,
'samesite' => 'None' // Obavezno za Cross-Origin
]);
Napomena: Ako koristite Laravel, postavite supports_credentials na true u datoteci config/cors.php i dodajte domenu prednjeg dijela u niz allowed_origins.
Korak 2: Ispravna konfiguracija klijenta (prednjeg dijela)
Čak i s potpunom konfiguracijom poslužitelja, preglednik još uvijek neće slati kolačiće osim ako na klijentskoj strani izričito ne deklarirate da je ovaj zahtjev "s vjerodajnicama".
Korištenje Fetch API-ja
fetch('https://api.example.com/user/profile', {
method: 'GET',
credentials: 'include' // Ova linija je ključ za rješavanje problema
})
.then(res => res.json())
.then(data => console.log(data));
Korištenje Axiosa
// Za određeni zahtjev
axios.get('https://api.example.com/user/profile', {
withCredentials: true
});
// Ili globalno za cijeli projekt
axios.defaults.withCredentials = true;
Kontrolni popis za rješavanje problema
Ako problem i dalje postoji nakon primjene gore navedenog, provjerite ove stavke redom:
- ✅ Jesu li obje strane na HTTPS-u? Atribut
Secureznači da kolačić radi samo na šifriranim vezama. Ako je vaša stranica na HTTP-u, preglednik neće prihvatiti kolačić. (Iznimka: razvojno okruženje nalocalhost) - ✅ Je li adresa Origin točna? Adresa
Access-Control-Allow-Originmora se točno podudarati s URL-om koji vidite u pregledniku. Čak i razlika uwwwili završnoj kosoj crti/uzrokovat će neuspjeh. - ✅ Je li OPTIONS zahtjev uspješan? Na kartici Network u alatima za razvoj preglednika provjerite Preflight zahtjev (s OPTIONS metodom). Na ovaj zahtjev mora se odgovoriti s kodom 200 ili 204 i ispravnim CORS zaglavljima.
- ✅ Je li kolačić pohranjen? U pregledniku idite na DevTools ← Application ← Cookies i provjerite je li kolačić pohranjen s atributima
SecureiSameSite=None. - ✅ Imate li posredni proxy ili vatrozid? Ponekad Cloudflare ili web poslužitelji poput Nginx-a prepisuju zaglavlja. Provjerite i njihovu konfiguraciju.
Sažetak
Slanje kolačića u zahtjevima između domena zahtijeva usklađivanje tri čimbenika: poslužitelj s Access-Control-Allow-Credentials: true i točnim Originom, kolačić s atributima SameSite=None; Secure i klijent s aktiviranim credentials: 'include' ili withCredentials: true. Slijedeći ove tri točke, problem će biti u potpunosti riješen.
Pouzdana infrastruktura, mir za programere
Ispravna implementacija CORS-a i upravljanje kolačićima samo su dio priče; infrastruktura na kojoj se izvodi vaš projekt također igra presudnu ulogu u stabilnosti i sigurnosti usluge:
Radib hosting — Brzi web hosting s potpunom podrškom za besplatni SSL i standardnu konfiguraciju zaglavlja; idealan izbor za hosting prednjeg i stražnjeg dijela vaših projekata.
Radib virtualni poslužitelj — Ako vaš projekt zahtijeva potpuni pristup, namjenske resurse i slobodu u konfiguraciji web poslužitelja (Nginx/Apache), Radib virtualni poslužitelji sa snažnim hardverom i stabilnom mrežom najbolji su izbor za profesionalne API-je.
Radib usluge otklanjanja pogrešaka i sigurnosti — Ako se nosite sa složenim CORS pogreškama, problemima s autentifikacijom ili sigurnosnim izazovima, Radib-ov tehnički tim, s dubokim iskustvom u rješavanju problema i osiguravanju web aplikacija, tu je da vam pomogne riješiti problem u korijenu.


