Co je CORS a jak nastavit přístup k datům

Autor: Zveřejněno

Stručně: CORS (Cross-Origin Resource Sharing) je mechanismus, kterým server může prohlížeči povolit, aby zpřístupnil odpověď skriptu běžícímu na jiném původu. Povolení určují hlavičky odpovědi serveru a jejich dodržování zajišťuje prohlížeč. Chyba CORS tedy obvykle znamená problém s oprávněním číst odpověď, nikoli nutně chybějící spojení se serverem.

Proč prohlížeč omezuje přístup mezi různými původy

Prohlížeče uplatňují zásadu stejného původu neboli same-origin policy. Ta omezuje možnost skriptu číst data z jiného původu. Stránka otevřená na jedné kartě tak nemůže libovolně stahovat a číst soukromá data z jiných služeb, ke kterým je uživatel přihlášený.

Původ (origin) tvoří trojice údajů: protokol, název hostitele a port. Změna byť jediného z nich znamená jiný původ. Cesta za názvem hostitele zde nehraje roli.

Pro stránku https://obchod.example vypadá srovnání takto:

Cílová adresaStejný původ?Důvod
https://obchod.example/produktyAnoMění se pouze cesta
https://api.obchod.exampleNeJiný název hostitele
http://obchod.exampleNeJiný protokol
https://sklep.example:8443NeJiný port než výchozí 443

CORS umožňuje serveru tuto zásadu řízeně uvolnit. Není to metoda HTTP, jako například GET nebo POST, ale mechanismus založený na hlavičkách HTTP.

Jednoduchý příklad: obchod načítá seznam produktů

Předpokládejme, že stránka běží na adrese https://obchod.example a API, tedy rozhraní zpřístupňující data aplikace, na adrese https://api.obchod.example. Skript stránky chce načíst produkty:

fetch('https://api.sklep.example/produkty')
  .then(odpoved => odpoved.json())
  .then(produkty => console.log(produkty));

Protože adresy mají různý původ, prohlížeč přidá k požadavku hlavičku určující původ stránky:

Origin: https://sklep.example

Server API může odpovědět daty a hlavičkou s povolením:

Access-Control-Allow-Origin: https://sklep.example

Prohlížeč tuto hodnotu porovná s původem stránky. Pokud povolení odpovídá, zpřístupní odpověď skriptu. Pokud hlavička chybí nebo uvádí jinou adresu, skript odpověď nemůže přečíst — i když server vrátil stav 200 OK.

Hlavička s povolením musí pocházet ze serveru API. Přidání Access-Control-Allow-Origin do kódu požadavku na straně prohlížeče problém nevyřeší.

Kdy prohlížeč nejprve posílá OPTIONS

Ne každý požadavek mezi různými původy se odešle rovnou. U některých prohlížeč nejprve provede preflight, tedy předběžný požadavek, kterým ověří povolení serveru.

Tento krok vyvolá například odeslání objednávky metodou POST s typem obsahu application/json. Stejně působí i použití hlavičky Authorization. Předběžný požadavek může vypadat takto:

OPTIONS /objednavky HTTP/1.1
Origin: https://sklep.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type

Server by měl odpovědět povolením, které zahrnuje původ, metodu a potřebné hlavičky:

Access-Control-Allow-Origin: https://sklep.example
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type

Teprve po úspěšném ověření prohlížeč odešle vlastní požadavek POST. Odpověď na tento požadavek POST musí rovněž obsahovat odpovídající hlavičku Access-Control-Allow-Origin.

Ne každý požadavek POST vyžaduje preflight. Záleží také na hlavičkách a typu přenášeného obsahu; běžný požadavek GET bez dalších hlaviček často předběžný požadavek nepotřebuje.

Cookies a hvězdička: dvě důležité nástrahy

Veřejné API, jehož odpovědi mají být dostupné skriptům z libovolného původu, může vracet:

Access-Control-Allow-Origin: *

Hvězdička však není vhodným řešením pro požadavky odesílané s cookies v režimu zahrnujícím přihlašovací údaje. V takovém případě může kód používat credentials: 'include' a server musí uvést konkrétní povolený původ a vrátit:

Access-Control-Allow-Origin: https://sklep.example
Access-Control-Allow-Credentials: true

Samotné nastavení CORS nezaručuje odeslání cookies. Platí také pravidla pro cookies, mimo jiné SameSite, a omezení prohlížeče na ochranu soukromí.

Pokud server obsluhuje několik důvěryhodných původů, měl by hodnotu hlavičky Origin ověřovat podle seznamu povolených hodnot. Automatické vracení libovolného přijatého původu spolu s povolením přihlašovacích údajů může zpřístupnit soukromé odpovědi. Pokud odpověď závisí na Origin, je nutné nastavit také Vary: Origin, aby mezipaměť rozlišovala jednotlivé varianty odpovědi.

Jak diagnostikovat chybu CORS

Ve vývojářských nástrojích prohlížeče otevřete kartu se síťovými požadavky a proveďte čtyři kontroly:

  1. Porovnejte protokol, hostitele a port stránky a API.
  2. Zkontrolujte, zda se odesílá požadavek OPTIONS a zda na něj server správně odpovídá.
  3. Prohlédněte si hlavičky odpovědi na vlastní požadavek, a to i při chybě serveru.
  4. Ověřte, zda povolení zahrnuje použitou metodu, hlavičky a případné přihlašovací údaje.

To, že volání funguje v curl, nedokazuje správné nastavení CORS: tento nástroj nevynucuje omezení prohlížeče. Ani nastavení mode: 'no-cors' neumožní čtení dat JSON — výsledkem je neprůhledná odpověď, jejíž obsah není skriptu dostupný.

CORS nenahrazuje přihlašování, kontrolu oprávnění ani ochranu před CSRF, tedy vynucením nechtěných akcí prostřednictvím jiné stránky. Některé požadavky mohou k serveru dorazit, i když je čtení odpovědi zablokované. Nápravu začněte nastavením API nebo prostředníka, kterého máte pod kontrolou, nikoli vypínáním zabezpečení prohlížeče.

Přečtěte si také

Zjistěte, jak PHP-FPM zpracovává požadavky PHP, čím se liší od webového serveru a jak nastavit procesy podle provozu a zdrojů hostingu.
Poznejte BIND, otevřený software pro server DNS: jak spravuje domény, jaké role plní a kdy se vyplatí provozovat vlastní server.
Zjistěte, k čemu slouží polský registr a číslo REGON, jak se liší od NIP a KRS a jak v oficiálním registru ověřit údaje o firmě.