Jak nastavit CORS pro REST API server (nginx)
Dnes jsem se potýkal s odmítnutím requestů odeslaných z prohlížeče na REST API server – ten je odmítl zpracovat z důvodu nastavené CORS politiky. Pokud se také potýkáte s tímto problémem, v tomto článku se dozvíte, jak ho vyřešit.
Trocha teorie
CORS, celým názvem Cross-Origin Resource Sharing, je nastavení (politika) serveru, která říká, jak naložit s požadavky z prohlížeče z jiných domén, než je doména daného serveru.
Máme-li doménu api.jetlio.com, na které běží API server a doménu cizidomena.cz, ze které vytvoříme AJAX požadavek na api.jetlio.com, bude tento požadavek odmítnut (není-li správně nastavena politika CORS).
Simple request
Splňuje-li požadavek náležitosti tzv. jednoduchého requestu (simple), pro jeho zpracování postačí nastavení hlavičky Access-Control-Allow-Origin
. V opačném případě se jedná o tzv. preflight request.
Požadavek je v běžných situacích simple v případě, že jsou splněny všechny následující podmínky:
- jedná se o GET, POST nebo HEAD požadavek
- v případě, že se jedná o POST požadavek,
Content-Type
nabývá jedné z následujících hodnot:text/plain
,application/x-www-form-urlencoded
,multipart/form-data
- požadavek neobsahuje jinou hlavičku než
Accept
,Accept-Language
,Content-Language
,Content-Type
,DPR
,Downlink
,Save-Data
,Viewport-Width
neboWidth
Preflight request
Nesplňuje-li požadavek podmínky simple požadavku, je označen jako preflight. V takové situaci prohlížeč ve skutečnosti pošle na server celkem požadavky dva.
V prvním (OPTION
) požadavku se dotáže na metody a hlavičky, které jsou v cross-site požadavku serverem povoleny. Pokud původní požadavek z prohlížeče podmínky splňuje, je odeslán na server také. Tam je následně zpracován a výsledná odpověď putuje zpět ke klientovi.
Nastavení v nginx
V konfiguračním souboru domény, u níž chcete CORS pro testovací účely nebo vývoj vhodně nastavit, upravte (nebo přidejte) následující nastavení:
location / {
# cors (simple request)
if ($request_method ~* "(GET|POST|PUT|PATCH|DELETE)") {
add_header Access-Control-Allow-Origin *;
}
# cors (preflight request)
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD";
add_header Access-Control-Allow-Headers "Authorization, Origin, X-Requested-With, Content-Type, Accept";
return 200;
}
}
Můžete odstranit nebo přidat další metody, které plánujete v REST API používat. V tomto případě jsou povoleny často používané GET, POST, PUT, PATCH a DELETE. Obdobně to platí u odesílaných hlaviček.
Až budete mít produkt hotový a otestovaný po funkční stránce, je důležité upravit nastavení Access-Control-Allow-Origin
, kde změňte hodnotu *
na seznam domén, ze kterých chcete požadavky povolit.
Kdybyste změnu neprovedli, celé CORS zabezpečení postrádá smysl. Existují ale samozřejmě i případy, kdy provoz ze všech domén povolit chcete – například u veřejných API služeb. Tam je na místě zase jiný druh zabezpečení (jako třeba omezení co do počtu požadavků z jedné IP adresy).
Pro podrobnější nastudování CORS problematiky doporučuji navštívit příslušnou stránku na webu MDN, která mi velmi pomohla: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS.