A modern webalkalmazások komplex rendszerek, amelyek gyakran számos különböző forrásból – szerverekről, API-król, felhőszolgáltatásokból – gyűjtik össze az adatokat, hogy dinamikus és interaktív felhasználói élményt nyújtsanak. Ezen interakciók motorja a HTTP protokoll, ám van egy alapvető biztonsági mechanizmus, amely jelentősen befolyásolja, hogyan oszthatók meg az erőforrások a különböző webhelyek között: ez a Same-Origin Policy (azonos eredetű politika). Amikor a webfejlesztők olyan helyzettel szembesülnek, ahol egy weboldalnak egy másik doménről kell erőforrásokat betöltenie, gyakran ütköznek a hírhedt CORS (Cross-Origin Resource Sharing – cross-origin erőforrásmegosztás) hibába. De mi is pontosan a CORS, miért van rá szükség, és hogyan teszi lehetővé a biztonságos és hatékony kommunikációt a domainek között?
A Same-Origin Policy (SOP) – A Biztonság Alapköve
Mielőtt belemerülnénk a CORS rejtelmeibe, elengedhetetlen megérteni annak előzményeit, a Same-Origin Policy-t. Ez a böngészőkben beépített, alapvető biztonsági mechanizmus korlátozza, hogy egy weboldal hogyan léphet interakcióba egy másik eredetről származó erőforrással. Az „eredet” fogalma a protokoll (pl. HTTP, HTTPS), a hosztnév (pl. example.com, api.example.com) és a portszám (pl. 80, 443) kombinációjára utal. Ha ezen három elem közül bármelyik eltér, az adott erőforrás eltérő eredetűnek minősül.
Miért olyan fontos az SOP?
Képzeljük el, hogy bejelentkezünk online banki felületünkre egy fülön. Ha az SOP nem létezne, egy másik böngészőfülön megnyitott, rosszindulatú weboldal könnyedén hozzáférhetne a banki oldalunkon lévő adatokhoz, és akár tranzakciókat is kezdeményezhetne a tudtunk nélkül. Az SOP pontosan ezt akadályozza meg: megvédi a felhasználókat a Cross-Site Request Forgery (CSRF) és más támadásoktól, biztosítva, hogy egy weboldal csak a saját eredetén belüli erőforrásokkal kommunikálhasson. Ez azt jelenti, hogy az example.com
-ról betöltött JavaScript kód nem férhet hozzá az api.anotherexample.com
-ról származó adatokhoz alapértelmezés szerint.
A CORS Megmentőként Érkezik: Mi is az a Cross-Origin Resource Sharing?
Bár az SOP elengedhetetlen a webbiztonsághoz, a modern webes architektúrák – mint például a Single Page Applications (SPA) vagy a Microservices alapú rendszerek – megkövetelik, hogy a böngészők biztonságosan tudjanak kommunikálni különböző eredetű erőforrásokkal. Itt jön képbe a CORS. A CORS egy HTTP-alapú mechanizmus, amely kiegészíti az SOP-t azáltal, hogy lehetővé teszi a szerverek számára, hogy jelezzék, mely eredetek jogosultak hozzáférni a náluk tárolt erőforrásokhoz. Egyszerűbben fogalmazva, a CORS egy engedélyező rendszer, amely a böngésző és a szerver közötti „alku” alapján dönti el, hogy egy cross-origin kérés biztonságos-e és teljesíthető-e.
A CORS működése a színfalak mögött: Egyszerű és Preflight kérések
A CORS kérések két fő kategóriába sorolhatók: az egyszerű kérések (simple requests) és a preflight kérések (preflighted requests). A böngésző dönti el, hogy melyik típust kell használnia a kérés jellemzői alapján.
Egyszerű kérések (Simple Requests)
Egy HTTP kérés akkor minősül egyszerűnek, ha a következő feltételeknek megfelel:
- Csak a következő metódusok egyike:
GET
,HEAD
,POST
. - Csak a böngésző által automatikusan beállított fejléceket (pl.
User-Agent
) vagy a következő „biztonságos” CORS fejléceket használja:Accept
Accept-Language
Content-Language
Content-Type
(de csak akkor, ha értékeapplication/x-www-form-urlencoded
,multipart/form-data
vagytext/plain
)Range
- Nincs `ReadableStream` objektum használva a kérésben.
Ha egy kérés egyszerűnek minősül, a böngésző közvetlenül elküldi a kérést az erőforrás szerverének, és hozzáadja az Origin
HTTP fejlécet, amely tartalmazza az eredeti weboldal eredetét (protokoll, hosztnév, port). A szerver ezután feldolgozza a kérést, és a válaszában hozzáadja az Access-Control-Allow-Origin
fejlécet, jelezve, hogy mely eredetek jogosultak az erőforrás elérésére. Ha az Origin
fejléc értéke megegyezik a szerver által engedélyezett értékek egyikével (vagy az *
wildcard-dal), a böngésző hozzáférést biztosít a válaszhoz. Ha nem, a böngésző blokkolja a választ, és CORS hibát jelez.
Preflight kérések (Preflight Requests) és az OPTIONS metódus
Minden olyan cross-origin kérés, amely nem felel meg az „egyszerű kérés” feltételeinek (pl. PUT
, DELETE
metódusok, egyéni fejlécek, más Content-Type
), egy preflight kéréssel kezdődik. Ez egy előzetes „ellenőrzés” a böngésző részéről, mielőtt elküldené a tényleges kérést. A böngésző egy HTTP OPTIONS kérést küld a szervernek, amelyben tájékoztatja a szervert arról, hogy milyen metódust, milyen fejléceket és milyen eredetből szándékozik használni a tényleges kérésben.
A preflight kérés fejlécei:
Origin
: Az eredeti weboldal eredete.Access-Control-Request-Method
: A tényleges kéréshez használni kívánt HTTP metódus (pl.PUT
).Access-Control-Request-Headers
: A tényleges kéréshez használni kívánt egyéni HTTP fejlécek (pl.X-Auth-Token
).
A szervernek erre az OPTIONS kérésre válaszolnia kell, jelezve, hogy elfogadja-e a tervezett kérést. Ha a szerver válasza pozitív (azaz a válaszfejlécek engedélyezik a kérést), akkor a böngésző elküldi a tényleges kérést. Ha a szerver nem engedélyezi, a böngésző blokkolja a tényleges kérést, és CORS hibát jelez. Ez a kétlépcsős folyamat extra biztonsági réteget nyújt, mivel a böngésző már a tényleges adatküldés előtt megtudja, hogy az művelet engedélyezett-e.
Kulcsfontosságú CORS Fejlécek: A Kommunikáció Nyelve
A CORS működésének alapját a HTTP fejlécek képezik. Lássuk a legfontosabbakat, amelyek a kérések és válaszok során szerepet játszanak:
Kérésfejlécek (Request Headers)
Origin
Ezt a fejlécet a böngésző automatikusan hozzáadja minden cross-origin kéréshez. Értéke az a protokoll, hosztnév és port, ahonnan a kérés származik (pl. https://mywebapp.com
). Ez az információ kritikus a szerver számára, hogy eldöntse, engedélyezi-e a hozzáférést.
Válaszfejlécek (Response Headers)
Ezeket a fejléceket a cél szervernek kell beállítania a válaszában, hogy jelezze a böngészőnek, mely eredetek és metódusok engedélyezettek.
Access-Control-Allow-Origin
Ez a legfontosabb CORS fejléc. Megadja, hogy melyik eredet (vagy eredetek) jogosultak az erőforrás elérésére. Például: Access-Control-Allow-Origin: https://mywebapp.com
. Ha minden eredet számára engedélyezni akarjuk a hozzáférést (fejlesztési környezetben vagy publikus API-k esetén), használhatjuk a *
(wildcard) karaktert: Access-Control-Allow-Origin: *
. Fontos megjegyezni, hogy wildcard használata esetén nem lehet kredenciálokat (lásd alább) küldeni.
Access-Control-Allow-Methods
Csak a preflight kérések válaszában szerepel. Megadja, hogy mely HTTP metódusok (pl. GET
, POST
, PUT
, DELETE
) engedélyezettek a cross-origin kérések során. Például: Access-Control-Allow-Methods: GET, POST, PUT
.
Access-Control-Allow-Headers
Szintén a preflight kérések válaszában szerepel. Felsorolja azokat az egyéni HTTP fejléceket, amelyeket a tényleges kérés tartalmazhat. Például: Access-Control-Allow-Headers: Content-Type, Authorization, X-Custom-Header
.
Access-Control-Allow-Credentials
Ez a fejléc jelzi a böngészőnek, hogy a szerver engedélyezi-e a hitelesítő adatok (pl. HTTP autentikációs adatok, cookie-k vagy kliensoldali SSL tanúsítványok) küldését a cross-origin kérésekkel. Értéke csak true
lehet, ha engedélyezett: Access-Control-Allow-Credentials: true
. Fontos: ha ez a fejléc true
, akkor az Access-Control-Allow-Origin
nem lehet *
, hanem konkrét eredetnek kell lennie. Ez egy fontos biztonsági intézkedés.
Access-Control-Expose-Headers
Alapértelmezés szerint a böngészők csak egy szűkített listát tesznek elérhetővé a JavaScript kód számára a válasz fejléceiből (pl. Content-Type
). Ha a szerver egyéni fejléceket szeretne elérhetővé tenni a kliensoldali kód számára (pl. egy API token a X-Api-Token
fejlécben), akkor azokat fel kell sorolni ebben a fejlécben: Access-Control-Expose-Headers: X-Api-Token, X-Rate-Limit
.
Access-Control-Max-Age
A preflight kérések válaszában szerepel. Megadja, hogy az OPTIONS kérés eredményeit mennyi ideig tárolhatja a böngésző gyorsítótárban (másodpercekben). Ez csökkentheti a felesleges OPTIONS kérések számát, optimalizálva a teljesítményt. Például: Access-Control-Max-Age: 86400
(24 óra).
Kredenciálok (Hitelesítő Adatok) Kezelése CORS-al
A CORS lehetővé teszi a hitelesítő adatok (mint például cookie-k, HTTP autentikációs adatok, `Authorization` fejlécek) küldését is cross-origin kérésekkel. Ehhez azonban mind a kliensoldalon, mind a szerveroldalon speciális konfigurációra van szükség:
- Kliensoldalon: Az `XMLHttpRequest` vagy `Fetch API` hívásnál be kell állítani a `withCredentials` opciót `true`-ra (pl. `fetch(‘…’, { credentials: ‘include’ })` vagy `xhr.withCredentials = true`).
- Szerveroldalon: A szervernek explicit módon hozzá kell adnia az
Access-Control-Allow-Credentials: true
fejlécet a válaszhoz. Ahogy korábban említettük, ebben az esetben azAccess-Control-Allow-Origin
nem lehet*
, hanem konkrét eredetet kell megadnia.
Enélkül a böngésző nem küldi el a kredenciálokat cross-origin kérésekkel, még akkor sem, ha egyébként elérhetők lennének.
Biztonsági Megfontolások és Best Practices
A CORS helytelen konfigurálása súlyos web biztonsági rést okozhat. Íme néhány bevált gyakorlat:
- Legszűkebb körű engedélyezés: Soha ne használja az
Access-Control-Allow-Origin: *
fejlécet éles környezetben, ha a kérések kredenciálokat is tartalmazhatnak, vagy ha az API érzékeny adatokat szolgáltat. Mindig adja meg explicit módon a megbízható eredeteket. - Csak szükséges metódusok és fejlécek engedélyezése: Ne engedélyezzen minden HTTP metódust és fejlécet, ha nincs rá szükség. Csak azokat adja meg, amelyekre valóban szükség van.
- A `Access-Control-Max-Age` használata: Használja ezt a fejlécet a preflight kérések optimalizálására, de ne állítsa túl magasra, hogy a biztonsági szabályok gyorsan frissülhessenek, ha szükséges.
- Szerveroldali ellenőrzés: Ne bízza kizárólag a böngészőre a biztonságot. Mindig végezzen szerveroldali validációt és autentikációt az összes bejövő kérésnél, függetlenül a CORS fejlécektől.
- HTTPS használata: Mindig használjon HTTPS-t az összes domainen, hogy biztosítsa a kommunikáció titkosítását.
Gyakori CORS Hibák és Hibaelhárítás
A CORS hibák a webfejlesztők mumusai. Általában olyankor jelentkeznek, amikor a böngésző blokkolja a választ, mert a szerver nem küldte el a megfelelő CORS válaszfejléceket, vagy azok nem egyeznek az Origin
fejlécben küldött eredettel.
Gyakori hibajelenségek:
- `Access to XMLHttpRequest at ‘…’ from origin ‘…’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.`
- `Preflight request for ‘…’ does not have HTTP ok status.`
- `The ‘Access-Control-Allow-Origin’ header contains multiple values ‘*, …’, but only one is allowed.`
Hibaelhárítási tippek:
- Böngésző fejlesztői eszközök: Ellenőrizze a „Network” (Hálózat) fület, nézze meg a HTTP kéréseket és a szerver válaszfejléceit. Keresse az
Origin
kérésfejlécet és azAccess-Control-*
válaszfejléceket. - Szerveroldali konfiguráció: Győződjön meg róla, hogy a szerver (pl. Apache, Nginx, Node.js Express, Python Flask) megfelelően van konfigurálva a CORS fejlécek hozzáadására.
- Proxy használata: Ha a szerver nem az Ön irányítása alatt áll, vagy egyszerűen nem tudja konfigurálni a CORS fejléceket, egy proxy szerver (amely saját domainjén fut) használatával elkerülheti a CORS problémákat, mivel a kérések ekkor azonos eredetűnek minősülnek a böngésző számára.
Alternatívák Rövid Áttekintése
Bár a CORS a preferált módszer a cross-origin erőforrásmegosztásra, érdemes megemlíteni néhány korábbi (vagy speciális esetekben még használt) alternatívát:
- JSONP (JSON with Padding): Egy régebbi technika, amely a `