← Cloudflare One / cloudflare-one / access-controls / applications / http-apps / authorization-cookie
CORS
Sdílení zdrojů mezi zdroji (CORS ↗) je mechanismus, který pomocí HTTP hlaviček uděluje webové aplikaci běžící na jednom originu oprávnění přistupovat k vybraným zdrojům na jiném originu. Webová aplikace provede cross-origin HTTP požadavek ve chvíli, kdy si vyžádá zdroj s jiným originem, než má sama, ať už jde o doménu, protokol nebo port.
Aby požadavek CORS mohl dosáhnout webu chráněného službou Access, musí obsahovat platný CF-Authorization cookie. To může v závislosti na typu požadavku vyžadovat další konfiguraci:
-
Jednoduché požadavky ↗ jsou odesílány přímo na origin, aniž by vyvolaly preflight požadavek. Pokyny ke konfiguraci najdete v Povolit jednoduché požadavky.
-
Preflight požadavky ↗ způsobí, že prohlížeč před odesláním skutečného požadavku odešle požadavek OPTIONS. Požadavek OPTIONS ověří, jaké metody a hlavičky origin povoluje. Pokyny ke konfiguraci najdete v Povolit preflight požadavky.
Povolit jednoduché požadavky
Pokud odešlete jednoduchý požadavek CORS na doménu chráněnou pomocí Access a ještě nejste přihlášeni, požadavek vrátí CORS error. Tuto chybu můžete vyřešit dvěma způsoby:
- Možnost 1, Přihlaste se a obnovte stránku.
- Možnost 2, Vytvořte Cloudflare Worker, který automaticky odesílá autentizační token. Tato metoda funguje pouze v případě, že oba weby zapojené do výměny CORS jsou za Access.
Ruční ověření
- Navštivte cílovou doménu ve svém prohlížeči. Zobrazí se přihlašovací stránka Access.
- Přihlaste se do cílové domény. Tím se vygeneruje
CF-Authorizationcookie. - Obnovte stránku, která odeslala požadavek CORS. Obnovení znovu odešle požadavek s nově vygenerovaným cookie.
Povolit preflight požadavky
Pokud odešlete preflight cross-origin požadavek na doménu chráněnou pomocí Access, požadavek OPTIONS vrátí 403 chybu. Tato chyba nastává bez ohledu na to, zda jste do domény přihlášeni. Je to proto, že prohlížeč záměrně nikdy neposílá cookies s požadavky OPTIONS. Cloudflare proto preflight požadavek zablokuje, což způsobí selhání výměny CORS.
Tuto chybu můžete vyřešit třemi způsoby:
- Možnost 1, Obejít požadavky OPTIONS na origin.
- Možnost 2, Nakonfigurujte Cloudflare tak, aby odpovídal na požadavek OPTIONS.
- Možnost 3, Vytvořte Cloudflare Worker, který automaticky odesílá autentizační token. Tato metoda funguje pouze v případě, že oba weby zapojené do výměny CORS jsou za Access.
Obejít požadavky OPTIONS na origin
Cloudflare můžete nakonfigurovat tak, aby posílal požadavky OPTIONS přímo na váš origin server. Chcete-li pro požadavky OPTIONS obejít Access:
- V Cloudflare dashboard ↗, přejděte na Zero Trust > Řízení přístupu > Aplikace.
- Najděte origin, který bude přijímat požadavky OPTIONS, a vyberte Konfigurovat.
- Přejděte na Pokročilá nastavení > Nastavení sdílení zdrojů mezi zdroji (CORS).
- Zapněte Obejít požadavky options na origin. Tím se odeberou veškerá stávající nastavení CORS pro tuto aplikaci.
I tak je důležité vynucovat CORS pro Access JWT: tuto možnost byste měli použít pouze v případě, že máte vynucování CORS nastaveno i na svém origin serveru.
Nakonfigurujte odpověď na preflight požadavky
Cloudflare můžete nakonfigurovat tak, aby na požadavek OPTIONS odpovídal místo vás. Požadavek OPTIONS se k vašemu origin serveru nikdy nedostane. Jakmile se preflight výměna vyřeší, prohlížeč následně odešle hlavní požadavek, který již obsahuje ověřovací cookie (za předpokladu, že jste se do domény chráněné Access přihlásili).
Chcete-li nakonfigurovat, jak Cloudflare reaguje na požadavky typu preflight:
-
V Cloudflare dashboard ↗, přejděte na Zero Trust > Řízení přístupu > Aplikace.
-
Najděte origin, který bude přijímat požadavky OPTIONS, a vyberte Konfigurovat.
-
Přejděte na Pokročilá nastavení > Nastavení sdílení zdrojů mezi zdroji (CORS).
-
Nakonfigurujte tyto Nastavení CORS ↗ tak, aby odpovídalo hlavičkám odpovědi odesílaným vaším origin serverem.
Pokud jste například nakonfigurovali
api.mysite.coma vrátit následující hlavičky:headers: { 'Access-Control-Allow-Origin': 'https://example.com', 'Access-Control-Allow-Credentials' : true, 'Access-Control-Allow-Methods': 'GET, OPTIONS', 'Access-Control-Allow-Headers': 'office', 'Content-Type': 'application/json', }poté přejděte na
api.mysite.comv Access a nakonfigurovat Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Methods, a Access-Control-Allow-Headers.
-
Vyberte Save.
-
(Volitelné) Konfiguraci můžete zkontrolovat odesláním požadavku OPTIONS na origin s
curl. Například,curl --head --request OPTIONS https://api.mysite.com \ --header 'origin: https://example.com' \ --header 'access-control-request-method: GET'výstupem by měla být odpověď podobná této:
HTTP/2 200 date: Tue, 24 May 2022 21:51:21 GMT vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers access-control-allow-origin: https://example.com access-control-allow-methods: GET access-control-allow-credentials: true expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=A%2FbOOWJio%2B%2FjuJv5NC%2FE3%2Bo1zBl2UdjzJssw8gJLC4lE1lzIUPQKqJoLRTaVtFd21JK1d4g%2BnlEGNpx0mGtsR6jerNfr2H5mlQdO6u2RdOaJ6n%2F%2BS%2BF9%2Fa12UromVLcHsSA5Y%2Fj72tM%3D"}],"group":"cf-nel","max_age":604800} nel: {"success_fraction":0.01,"report_to":"cf-nel","max_age":604800} server: cloudflare cf-ray: 7109408e6b84efe4-EWR
Odesílání ověřovacího tokenu pomocí Cloudflare Worker
Pokud máte dvě pobočky chráněné pomocí Cloudflare Access, example.com a api.mysite.com, požadavky mezi těmito dvěma budou podléhat kontrolám CORS. Uživatelé, kteří se přihlásí do example.com obdrží soubor cookie pro example.com. Když si prohlížeč uživatele vyžádá api.mysite.com, Cloudflare Access hledá cookie specifické pro api.mysite.com. Požadavek selže, pokud se uživatel ještě nepřihlásil do api.mysite.com.
Chcete-li se vyhnout dvojímu přihlašování, můžete vytvořit Cloudflare Worker, který automaticky odesílá přihlašovací údaje na api.mysite.com.
Předpoklady
- účet Workers
wranglerinstalaceexample.comaapi.mysite.comdomény chráněno pomocí Access
1. Vygenerujte service token
Postupujte podle tyto pokyny a vygenerovat nový service token Access. Zkopírujte Client ID a Client Secret na bezpečné místo, protože je budete potřebovat v pozdějším kroku.
2. Přidejte zásadu Service Auth
-
V Cloudflare dashboard ↗, přejděte na Zero Trust > Řízení přístupu > Aplikace.
-
Najděte svůj
api.mysite.comaplikaci a vyberte Konfigurovat. -
Vyberte Zásady kartě.
-
Přidejte následující zásadu:
Akce Typ pravidla Selektor Service Auth Include Service Token
3. Vytvořte nový Worker
Otevřete terminál a spusťte následující příkaz:
npm create cloudflare@latest -- authentication-workerTímto budete vyzváni k instalaci create-cloudflare ↗ balíček a provede vás nastavením.
Při nastavení vyberte následující možnosti:
- Pro S čím byste chtěli začít?, vyberte
Hello World example. - Pro Jakou šablonu chcete použít?, vyberte
Worker only. - Pro Jaký jazyk chcete použít?, vyberte
JavaScript. - Pro Chcete používat git pro správu verzí?, vyberte
Yes. - Pro Chcete nasadit svou aplikaci?, vyberte
No(před nasazením provedeme ještě několik změn).
Přejděte do adresáře projektu.
cd authentication-workerOtevřete /src/index.js a odstraňte stávající kód a vložte následující příklad:
// The hostname where your API lives
const originalAPIHostname = "api.mysite.com";
export default {
async fetch(request, env) {
// Change just the host. If the request comes in on example.com/api/name, the new URL is api.mysite.com/api/name
const url = new URL(request.url);
url.hostname = originalAPIHostname;
// If your API is located on api.mysite.com/anyname (without "api/" in the path),
// remove the "api/" part of example.com/api/name
// url.pathname = url.pathname.substring(4)
// Best practice is to always use the original request to construct the new request
// to clone all the attributes. Applying the URL also requires a constructor
// since once a Request has been constructed, its URL is immutable.
const newRequest = new Request(url.toString(), request);
newRequest.headers.set("cf-access-client-id", env.CF_ACCESS_CLIENT_ID);
newRequest.headers.set("cf-access-client-secret", env.CF_ACCESS_CLIENT_SECRET);
try {
const response = await fetch(newRequest);
// Copy over the response
const modifiedResponse = new Response(response.body, response);
// Delete the set-cookie from the response so it doesn't override existing cookies
modifiedResponse.headers.delete("set-cookie");
return modifiedResponse;
} catch (e) {
return new Response(JSON.stringify({ error: e.message }), {
status: 500,
});
}
},
};Poté nasaďte Worker do svého účtu Cloudflare:
npx wrangler deploy4. Nakonfigurujte Worker
-
V Cloudflare dashboard ↗, přejděte do Workers & Pages stránce.
Přejděte na Workers & Pages ↗ -
Vyberte nově vytvořeného Workera.
-
V Triggery kartě přejděte na Trasy a přidejte
example.com/api/*. Worker je umístěn na podcestěexample.coma zabraňte mezizdrojovému (cross-origin) požadavku. -
V Nastavení kartě vyberte Proměnné.
-
V části Proměnné prostředí, přidejte následující tajné proměnné:
CF_ACCESS_CLIENT_ID=<service token Client ID>CF_ACCESS_CLIENT_SECRET=<service token Client Secret>
Client ID a Client Secret se kopírují z vašeho token služby.
- Povolte Šifrovat možnost pro každou proměnnou a vyberte Save.
5. Aktualizujte adresy URL požadavků HTTP
Upravte svůj example.com aplikaci, aby odesílala všechny požadavky na example.com/api/ místo api.mysite.com.
Požadavky HTTP by nyní měly bez problémů fungovat mezi dvěma různými doménami chráněnými Access. Když se uživatel přihlásí do example.com, prohlížeč odešle požadavek na Worker místo na api.mysite.com. Worker přidá token služby Access do hlaviček požadavku a poté požadavek přesměruje na api.mysite.com. Protože token služby odpovídá zásadě Service Auth, uživatel se už nemusí přihlašovat k api.mysite.com.
Řešení potíží
Obecně doporučujeme při řešení problémů s CORS následující kroky:
- Zachyťte soubor HAR s popisem problému a zároveň zaznamenejte výstup konzole JS. Samotný soubor HAR totiž neposkytne úplný přehled o příčině problémů s cross-origin.
- Ujistěte se, že aplikace nastavila
credentials: 'same-origin've všech požadavcích fetch nebo XHR. - Pokud používáte nastavení cross-origin ↗ u tagů script musí být nastaveny na hodnotu "use-credentials".