Odhalte tajemství CORS a naučte se bezpečně povolovat mezidoménové požadavky. Komplexní průvodce od základů po pokročilé konfigurace pro plynulou a bezpečnou komunikaci.
Demystifikace CORS: Komplexní průvodce sdílením zdrojů mezi různými původy
V dnešním propojeném světě webu aplikace často potřebují přistupovat ke zdrojům z různých původů. Právě zde přichází na řadu Cross-Origin Resource Sharing (CORS). CORS je klíčový bezpečnostní mechanismus, který řídí, jak webové prohlížeče zpracovávají požadavky z jednoho původu (doména, protokol a port) na jiný původ. Porozumění CORS je pro každého webového vývojáře zásadní pro tvorbu bezpečných a funkčních webových aplikací.
Co je politika stejného původu (Same-Origin Policy)?
Než se ponoříme do CORS, je důležité porozumět politice stejného původu (Same-Origin Policy, SOP). SOP je základní bezpečnostní mechanismus implementovaný ve webových prohlížečích. Jeho účelem je zabránit škodlivým skriptům na jedné webové stránce v přístupu k citlivým datům na jiné webové stránce. Původ je definován kombinací protokolu (např. HTTP nebo HTTPS), domény (např. example.com) a čísla portu (např. 80 nebo 443). Dvě URL adresy jsou považovány za adresy stejného původu, pokud sdílejí stejný protokol, doménu a port.
Příklad:
http://example.com/app1
ahttp://example.com/app2
- Stejný původ (stejný protokol, doména a port)https://example.com/app1
ahttp://example.com/app1
- Různý původ (jiný protokol)http://example.com:8080/app1
ahttp://example.com/app1
- Různý původ (jiný port)http://sub.example.com/app1
ahttp://example.com/app1
- Různý původ (jiná subdoména – považována za jinou doménu)
SOP omezuje skriptům přístup ke zdrojům z jiného původu, pokud nejsou zavedena specifická opatření, jako je CORS, která to povolují.
Proč je CORS nezbytný?
Ačkoli je politika stejného původu pro bezpečnost životně důležitá, může být také omezující. Mnoho moderních webových aplikací se spoléhá na získávání dat z různých serverů, jako jsou API nebo sítě pro doručování obsahu (CDN). CORS poskytuje kontrolovaný způsob, jak uvolnit SOP a povolit legitimní požadavky mezi různými původy při zachování bezpečnosti.
Představte si scénář, kdy webová aplikace hostovaná na http://example.com
potřebuje načíst data z API serveru hostovaného na http://api.example.net
. Bez CORS by prohlížeč tento požadavek kvůli SOP zablokoval. CORS umožňuje API serveru explicitně specifikovat, které původy mají povolen přístup k jeho zdrojům, což umožňuje webové aplikaci správně fungovat.
Jak funguje CORS: Základy
CORS funguje prostřednictvím série HTTP hlaviček vyměňovaných mezi klientem (prohlížečem) a serverem. Server používá tyto hlavičky k informování prohlížeče, zda má povolen přístup k požadovanému zdroji. Klíčovou zúčastněnou HTTP hlavičkou je Access-Control-Allow-Origin
.
Scénář 1: Jednoduchý požadavek
"Jednoduchý požadavek" je požadavek GET, HEAD nebo POST, který splňuje specifická kritéria (např. hlavička Content-Type
je jedna z application/x-www-form-urlencoded
, multipart/form-data
nebo text/plain
). V tomto případě prohlížeč odešle požadavek přímo na server a server odpoví s hlavičkou Access-Control-Allow-Origin
.
Požadavek klienta (z http://example.com):
GET /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Odpověď serveru (z http://api.example.net):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json
{
"data": "Some data from the server"
}
V tomto příkladu server odpovídá s Access-Control-Allow-Origin: http://example.com
, což znamená, že požadavky z http://example.com
jsou povoleny. Pokud původ v požadavku neodpovídá hodnotě v hlavičce Access-Control-Allow-Origin
(nebo pokud hlavička není přítomna), prohlížeč zablokuje odpověď a zabrání klientskému skriptu v přístupu k datům.
Scénář 2: Preflight požadavek (pro složité požadavky)
Pro složitější požadavky, jako jsou ty používající HTTP metody jako PUT, DELETE, nebo ty s vlastními hlavičkami, provede prohlížeč "preflight" požadavek pomocí HTTP metody OPTIONS. Tento preflight požadavek žádá server o povolení před odesláním skutečného požadavku. Server odpoví s hlavičkami, které specifikují, jaké metody, hlavičky a původy jsou povoleny.
Preflight požadavek klienta (z http://example.com):
OPTIONS /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Odpověď serveru (z http://api.example.net):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, PUT, DELETE
Access-Control-Allow-Headers: X-Custom-Header, Content-Type
Access-Control-Max-Age: 3600
Vysvětlení hlaviček:
Access-Control-Allow-Origin: http://example.com
- Označuje, že požadavky zhttp://example.com
jsou povoleny.Access-Control-Allow-Methods: GET, PUT, DELETE
- Specifikuje HTTP metody povolené pro požadavky mezi různými původy.Access-Control-Allow-Headers: X-Custom-Header, Content-Type
- Uvádí seznam povolených vlastních hlaviček ve skutečném požadavku.Access-Control-Max-Age: 3600
- Specifikuje dobu (v sekundách), po kterou může být odpověď na preflight požadavek uložena v mezipaměti prohlížeče. To pomáhá snížit počet preflight požadavků.
Pokud odpověď serveru na preflight požadavek naznačuje, že je požadavek povolen, prohlížeč pokračuje se skutečným požadavkem. V opačném případě prohlížeč požadavek zablokuje.
Skutečný požadavek klienta (z http://example.com):
PUT /data HTTP/1.1
Host: api.example.net
Origin: http://example.com
X-Custom-Header: some-value
Content-Type: application/json
{
"data": "Some data to be updated"
}
Odpověď serveru (z http://api.example.net):
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Content-Type: application/json
{
"status": "Data updated successfully"
}
Běžné CORS hlavičky
Zde je přehled klíčových CORS hlaviček, kterým je třeba porozumět:
Access-Control-Allow-Origin
: Toto je nejzásadnější hlavička. Specifikuje původ(y), kterým je povolen přístup ke zdroji. Možné hodnoty zahrnují:- Specifický původ (např.
http://example.com
). *
(wildcard): Toto povoluje požadavky z jakéhokoli původu. Používejte s opatrností, protože to může ohrozit bezpečnost, pokud jsou zapojena citlivá data. Obecně by se mělo v produkčních prostředích vyhnout.
- Specifický původ (např.
Access-Control-Allow-Methods
: Tato hlavička specifikuje HTTP metody (např. GET, POST, PUT, DELETE), které jsou povoleny pro požadavky mezi různými původy. Používá se v odpovědi na preflight požadavek.Access-Control-Allow-Headers
: Tato hlavička uvádí seznam vlastních hlaviček, které jsou povoleny v požadavcích mezi různými původy. Používá se také v odpovědi na preflight požadavek.Access-Control-Allow-Credentials
: Tato hlavička udává, zda server povoluje zahrnutí přihlašovacích údajů (např. cookies, autorizační hlavičky) v požadavcích mezi různými původy. Měla by být nastavena natrue
, pokud potřebujete posílat přihlašovací údaje. Na straně klienta je také třeba nastavitwithCredentials = true
na objektu XMLHttpRequest.Access-Control-Expose-Headers
: Ve výchozím nastavení prohlížeče zpřístupňují klientským skriptům pouze omezenou sadu hlaviček odpovědi (např.Cache-Control
,Content-Language
,Content-Type
,Expires
,Last-Modified
,Pragma
). Pokud chcete zpřístupnit další hlavičky, musíte je uvést v hlavičceAccess-Control-Expose-Headers
.Access-Control-Max-Age
: Tato hlavička specifikuje maximální dobu (v sekundách), po kterou může prohlížeč ukládat preflight požadavek do mezipaměti. Delší hodnota snižuje počet preflight požadavků a zlepšuje výkon.
CORS v různých serverových jazycích
Implementace CORS obvykle zahrnuje konfiguraci vaší serverové aplikace tak, aby posílala příslušné CORS hlavičky. Zde jsou příklady, jak to udělat v různých jazycích a frameworcích:
Node.js s Express
Můžete použít middleware balíček cors
:
const express = require('express');
const cors = require('cors');
const app = express();
// Povolit CORS pro všechny původy (V PRODUKCI POUŽÍVAT OPATRNĚ)
app.use(cors());
// Alternativně, nakonfigurujte CORS pro specifické původy
// app.use(cors({
// origin: 'http://example.com'
// }));
app.get('/data', (req, res) => {
res.json({ message: 'This is CORS-enabled for all origins!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Python s Flask
Můžete použít rozšíření Flask-CORS
:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
# Alternativně, nakonfigurujte CORS pro specifické původy
# CORS(app, resources={r"/api/*": {"origins": "http://example.com"}})
@app.route("/data")
def hello():
return {"message": "This is CORS-enabled for all origins!"}
if __name__ == '__main__':
app.run(debug=True)
Java se Spring Boot
CORS můžete konfigurovat ve své Spring Boot aplikaci pomocí anotací nebo konfiguračních tříd:
Použití anotací:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://example.com") // Povolit požadavky z http://example.com
public class DataController {
@GetMapping("/data")
public String getData() {
return "This is CORS-enabled for http://example.com!";
}
}
Použití konfigurace:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/data")
.allowedOrigins("http://example.com") // Povolit požadavky z http://example.com
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*");
}
}
PHP
"This is CORS-enabled for http://example.com!");
echo json_encode($data);
?>
CORS a bezpečnostní aspekty
Ačkoli CORS umožňuje požadavky mezi různými původy, je klíčové jej implementovat bezpečně. Zde jsou některé důležité aspekty:
- Vyhněte se používání
*
proAccess-Control-Allow-Origin
v produkci: To povoluje požadavky z jakéhokoli původu, což může představovat bezpečnostní riziko. Místo toho explicitně specifikujte původy, které mají povolen přístup k vašim zdrojům. - Validujte hlavičku
Origin
na straně serveru: I když používáte framework, který se stará o konfiguraci CORS, je dobrým zvykem validovat hlavičkuOrigin
na straně serveru, abyste zajistili, že požadavek přichází z očekávaného původu. - Buďte obezřetní s
Access-Control-Allow-Credentials
: Pokud používáte přihlašovací údaje (např. cookies, autorizační hlavičky), ujistěte se, že máte na straně serveru nastavenoAccess-Control-Allow-Credentials: true
a na straně klientawithCredentials = true
. Buďte si však vědomi, že použitíAccess-Control-Allow-Origin: *
není povoleno, když jeAccess-Control-Allow-Credentials
nastaveno natrue
. Musíte explicitně specifikovat povolené původy. - Správně nakonfigurujte
Access-Control-Allow-Methods
aAccess-Control-Allow-Headers
: Povolte pouze ty HTTP metody a hlavičky, které jsou nezbytné pro správné fungování vaší aplikace. To pomáhá snížit plochu pro útok. - Používejte HTTPS: Vždy používejte HTTPS pro své webové aplikace a API k ochraně dat při přenosu.
Řešení problémů s CORS
Problémy s CORS mohou být frustrující na ladění. Zde jsou některé běžné problémy a jak je řešit:
- "No 'Access-Control-Allow-Origin' header is present on the requested resource": Toto je nejčastější chyba CORS. Znamená to, že server ve své odpovědi neposílá hlavičku
Access-Control-Allow-Origin
. Zkontrolujte dvakrát svou konfiguraci na straně serveru, abyste se ujistili, že je hlavička správně odesílána. - "Response to preflight request doesn't pass access control check: It does not have HTTP ok status": Tato chyba naznačuje, že preflight požadavek selhal. To se může stát, pokud server není nakonfigurován pro zpracování OPTIONS požadavků nebo pokud hlavičky
Access-Control-Allow-Methods
neboAccess-Control-Allow-Headers
nejsou správně nakonfigurovány. - "The value of the 'Access-Control-Allow-Origin' header in the response is not equal to the origin in the request": Tato chyba znamená, že původ v požadavku neodpovídá hodnotě v hlavičce
Access-Control-Allow-Origin
. Ujistěte se, že server v odpovědi posílá správný původ. - Mezipaměť prohlížeče: Někdy mohou prohlížeče ukládat odpovědi CORS do mezipaměti, což může vést k neočekávanému chování. Zkuste vymazat mezipaměť prohlížeče nebo použít jiný prohlížeč, abyste zjistili, zda to problém vyřeší. Můžete také použít hlavičku
Access-Control-Max-Age
k řízení, jak dlouho prohlížeč ukládá odpověď na preflight požadavek do mezipaměti.
Nástroje pro ladění:
- Nástroje pro vývojáře v prohlížeči: Použijte nástroje pro vývojáře v prohlížeči (obvykle se otevírají stisknutím F12) k inspekci síťových požadavků a odpovědí. Hledejte hlavičky související s CORS a chybové zprávy.
- Online CORS Checkery: Existují online nástroje, které vám mohou pomoci testovat vaši konfiguraci CORS. Tyto nástroje odešlou požadavek na váš server a analyzují hlavičky odpovědi, aby identifikovaly potenciální problémy.
Pokročilé scénáře CORS
Zatímco základní koncepty CORS jsou relativně přímočaré, existují některé pokročilejší scénáře, které je třeba zvážit:
- CORS se subdoménami: Pokud potřebujete povolit požadavky z více subdomén (např.
app1.example.com
,app2.example.com
), nemůžete jednoduše použít zástupný znak jako*.example.com
v hlavičceAccess-Control-Allow-Origin
. Místo toho budete muset dynamicky generovat hlavičkuAccess-Control-Allow-Origin
na základě hlavičkyOrigin
v požadavku. Nezapomeňte validovat původ proti bílé listině povolených subdomén, abyste předešli bezpečnostním zranitelnostem. - CORS s více původy: Pokud potřebujete povolit požadavky z více specifických původů, nemůžete specifikovat více původů v hlavičce
Access-Control-Allow-Origin
(např.Access-Control-Allow-Origin: http://example.com, http://another.com
je neplatné). Místo toho budete muset dynamicky generovat hlavičkuAccess-Control-Allow-Origin
na základě hlavičkyOrigin
v požadavku. - CORS a CDN: Při použití CDN k servírování vašeho API musíte nakonfigurovat CDN tak, aby předávala hlavičku
Origin
vašemu originálnímu serveru a správně ukládala do mezipaměti hlavičkuAccess-Control-Allow-Origin
. Konkrétní pokyny naleznete v dokumentaci vašeho poskytovatele CDN.
Doporučené postupy pro CORS
Pro zajištění bezpečné a efektivní implementace CORS dodržujte tyto doporučené postupy:
- Princip nejmenších privilegií: Povolte pouze minimální sadu původů, metod a hlaviček, které jsou nezbytné pro správné fungování vaší aplikace.
- Pravidelně kontrolujte konfiguraci CORS: Jak se vaše aplikace vyvíjí, pravidelně kontrolujte svou konfiguraci CORS, abyste zajistili, že je stále vhodná a bezpečná.
- Používejte framework nebo knihovnu: Využijte existující frameworky nebo knihovny, které poskytují vestavěnou podporu CORS. To může zjednodušit implementaci a snížit riziko chyb.
- Monitorujte porušení CORS: Implementujte monitorování pro detekci a reakci na potenciální porušení CORS.
- Zůstaňte aktuální: Sledujte nejnovější specifikace CORS a bezpečnostní doporučení.
Závěr
CORS je klíčový bezpečnostní mechanismus, který umožňuje kontrolované požadavky mezi různými původy ve webových aplikacích. Porozumění tomu, jak CORS funguje a jak jej správně nakonfigurovat, je pro každého webového vývojáře zásadní. Dodržováním pokynů a doporučených postupů uvedených v tomto komplexním průvodci můžete vytvářet bezpečné a funkční webové aplikace, které plynule komunikují se zdroji z různých původů.
Nezapomeňte vždy upřednostňovat bezpečnost a vyhýbat se příliš benevolentním konfiguracím CORS. Pečlivým zvážením bezpečnostních důsledků vašeho nastavení CORS můžete chránit své aplikace a data před neoprávněným přístupem.
Doufáme, že vám tento průvodce pomohl demystifikovat CORS. Šťastné kódování!