Współdzielenie zasobów pomiędzy serwerami z różnych domen (CORS)

Bezpieczne udostępnianie zasobów z innych domen

Mariko Kosaka

Zasada tej samej domeny w przeglądarce blokuje odczyt zasobu z innego źródła. Ten mechanizm uniemożliwia złośliwym witrynom odczyt danych innych witryn, ale jednocześnie zapobiega uprawnionym użyciu.

Nowoczesne aplikacje internetowe często chcą uzyskiwać zasoby z innego źródła, np. przez pobieranie danych JSON z innej domeny lub wczytywanie obrazów z innej witryny do elementu <canvas>. Mogą to być zasoby publiczne, które powinny być dostępne dla każdego, ale zasady dotyczące tego samego pochodzenia blokują ich użycie. Deweloperzy korzystali dotychczas z obejść takich jak JSONP.

Narzędzie CORS rozwiązuje ten problem w ustandaryzowany sposób. Włączenie CORS pozwala serwerowi poinformować przeglądarkę, że może używać dodatkowego źródła.

Jak działa żądanie zasobu w przeglądarce?

żądanie i odpowiedź
Ilustrowane żądania klienta i odpowiedzi serwera.

Przeglądarka i serwer mogą wymieniać dane w sieci przy użyciu protokołu Hypertext Transfer Protocol (HTTP). HTTP określa reguły komunikacji między żądaniem a użytkownikiem, w tym informacje potrzebne do pozyskania zasobu.

Nagłówek HTTP negocjuje wymianę wiadomości między klientem a serwerem i służy do określania dostępu. Zarówno żądanie przeglądarki, jak i wiadomość z odpowiedzią serwera są podzielone na nagłówek i treść.

Informacje o wiadomości, takie jak typ lub kodowanie wiadomości. Nagłówek może zawierać różne informacje wyrażone w parach klucz-wartość. Nagłówki żądania i odpowiedzi zawierają różne informacje.

Przykładowy nagłówek żądania

Accept: text/html
Cookie: Version=1

Taki nagłówek jest odpowiednikiem wyrażenia „Chcę w odpowiedzi otrzymywać kod HTML. Mam tu taki plik cookie”.

Przykładowy nagłówek odpowiedzi

Content-Encoding: gzip
Cache-Control: no-store

Ten nagłówek jest odpowiednikiem komunikatu „Dane w tej odpowiedzi są zakodowane w gzip. Nie zapisuj w pamięci podręcznej”.

Treść

Wiadomość. Może to być zwykły tekst, plik binarny obrazu, plik JSON, HTML lub wiele innych.

Jak działa CORS?

Zasada dotycząca tej samej domeny informuje przeglądarkę, że ma blokować żądania z innych domen. Gdy potrzebujesz zasobu publicznego z innego źródła, serwer udostępniający zasoby informuje przeglądarkę, że źródło wysyłające żądanie może uzyskać dostęp do jego zasobu. Przeglądarka zapamiętuje te informacje i pozwala na udostępnianie zasobów między domenami.

Krok 1. Żądanie klienta (przeglądarki)

Gdy przeglądarka wysyła żądanie z innej domeny, dodaje nagłówek Origin z bieżącym źródłem (schematem, hostem i portem).

Krok 2. Odpowiedź serwera

Gdy serwer zobaczy ten nagłówek i zechce zezwolić na dostęp, dodaje do odpowiedzi nagłówek Access-Control-Allow-Origin, określając źródło żądania (lub parametr *, który zezwala na dowolne źródło).

Krok 3. Przeglądarka otrzymuje odpowiedź

Gdy przeglądarka widzi tę odpowiedź z odpowiednim nagłówkiem Access-Control-Allow-Origin, udostępnia dane odpowiedzi witrynie klienta.

Udostępnij dane logowania CORS

Ze względu na ochronę prywatności CORS jest zwykle używane w przypadku żądań anonimowych, w przypadku których nie można zidentyfikować zgłaszającego. Jeśli chcesz wysyłać pliki cookie, gdy używasz CORS, który może identyfikować nadawcę, musisz dodać do żądania i odpowiedzi dodatkowe nagłówki.

Prośba

Dodaj credentials: 'include' do opcji pobierania, tak jak w poniższym przykładzie. Obejmuje to plik cookie z takim żądaniem:

fetch('https://example.com', {
  mode: 'cors',
  credentials: 'include'
})

Odpowiedź

Access-Control-Allow-Origin musi być ustawiony na konkretny punkt początkowy (bez symbolu wieloznacznego z użyciem symbolu *), a Access-Control-Allow-Credentials musi być ustawiony na wartość true.

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

Żądania wstępne dotyczące złożonych wywołań HTTP

Gdy aplikacja internetowa wysyła złożone żądanie HTTP, przeglądarka dodaje żądanie procesu wstępnego na początku łańcucha żądań.

Specyfikacja CORS definiuje złożone żądanie w ten sposób:

  • Żądanie, które wykorzystuje metody inne niż GET, POST lub HEAD.
  • Żądanie zawierające nagłówki inne niż Accept, Accept-Language lub Content-Language.
  • Żądanie, które ma nagłówek Content-Type inny niż application/x-www-form-urlencoded, multipart/form-data lub text/plain.

Przeglądarki automatycznie tworzą niezbędne żądania procesów wstępnych i wysyłają je przed faktyczną wiadomością z żądaniem. Żądanie procesu wstępnego to żądanie OPTIONS, podobne do tego:

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

Po stronie serwera aplikacja odbierająca żądanie odpowiada na żądanie wstępne, podając informacje o metodach akceptowanych przez aplikację z tej źródła:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

Odpowiedź serwera może też zawierać nagłówek Access-Control-Max-Age, który określa czas (w sekundach) przechowywania w pamięci podręcznej wyników procesów wstępnych. Dzięki temu klient może wysyłać wiele złożonych żądań bez konieczności powtarzania żądania wstępnego.