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

Bezpieczne udostępnianie zasobów między domenami

Mariko Kosaka

Zasada dotycząca tego samego pochodzenia w przeglądarce blokuje odczyt zasobu z innego pochodzenia. Ten mechanizm uniemożliwia złośliwym witrynom odczytywanie danych z innych witryn, ale uniemożliwia też ich legalne wykorzystywanie.

Nowoczesne aplikacje internetowe często potrzebują zasobów z innego źródła, na przykład danych JSON z innej domeny lub obrazów z innej witryny do elementu <canvas>. Mogą to być zasoby publiczne, które powinny być dostępne do odczytu dla wszystkich, ale zasady dotyczące tego samego źródła blokują ich użycie. Deweloperzy korzystali z różnych obejść komunikatu o błędzie, np. z JSONP.

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

Jak działa żądanie zasobu w internecie?

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

Przeglądarka i serwer mogą wymieniać dane w sieci za pomocą protokołu HyperText Transfer Protocol (HTTP). HTTP określa reguły komunikacji między osobą wysyłającą żądanie a osobą odpowiadającą na nie, w tym informacje potrzebne do uzyskania zasobu.

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

informacje o wiadomości, takie jak typ wiadomości lub jej kodowanie; Nagłówek może zawierać różne informacje wyrażone jako pary klucz-wartość. Nagłówek żądania i nagłówek odpowiedzi zawierają różne informacje.

Przykładowy nagłówek żądania

Accept: text/html
Cookie: Version=1

Ten nagłówek jest równoważny z oświadczeniem „Chcę otrzymać odpowiedź w formacie HTML”. Oto mój plik cookie.

Przykładowy nagłówek odpowiedzi

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

Ten nagłówek jest równoważny stwierdzeniu „Dane w tej odpowiedzi są zakodowane za pomocą gzip. Nie przechowuj tego w pamięci podręcznej”.

Treść

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

Jak działa CORS?

Zasada dotycząca tego samego pochodzenia mówi przeglądarce, aby blokowała żądania z wielu źródeł. Gdy potrzebujesz zasobu publicznego z innego źródła, serwer dostarczający zasób informuje przeglądarkę, że źródło wysyłające żądanie może uzyskać dostęp do tego zasobu. Przeglądarka zapamięta to i zezwoli na udostępnianie zasobu w ramach innych domen.

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 (schemat, host i port).

Krok 2. Odpowiedź serwera

Gdy serwer zobaczy ten nagłówek i zechce zezwolić na dostęp, doda do odpowiedzi nagłówek Access-Control-Allow-Origin, podając w nim źródło żądania (lub *, aby zezwolić na dowolne źródło).

Krok 3. Przeglądarka otrzymuje odpowiedź

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

Udostępnianie danych logowania za pomocą CORS

Ze względu na ochronę prywatności współdzielenie zasobów pomiędzy serwerami z różnych domen jest zwykle używane w przypadku anonimowych żądań, w których nie jest identyfikowany podmiot przesyłający żądanie. Jeśli chcesz wysyłać pliki cookie podczas korzystania z interfejsu CORS, który może zidentyfikować nadawcę, musisz dodać dodatkowe nagłówki do żądania i odpowiedzi.

Żądanie

Dodaj credentials: 'include' do opcji pobierania, jak w tym przykładzie. Obejmuje to plik cookie z żądaniem w takiej postaci:

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

Odpowiedź

Access-Control-Allow-Origin musi być ustawiony na konkretne źródło (bez użycia symbolu zapytania *), a Access-Control-Allow-Credentials musi być ustawiony na true.

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

żądania wstępne w przypadku złożonych wywołań HTTP;

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

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

  • żądanie, które używa metod innych 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 wstępne i wysyłają je przed wysłaniem właściwej wiadomości z żądaniem. Żądanie procesu wstępnego to żądanie OPTIONS, takie jak to:

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

Po stronie serwera aplikacja, która odbiera żądanie, odpowiada na żądanie wstępne, podając informacje o metodach akceptowanych przez aplikację z tego ź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, aby określić czas trwania w sekundach, który ma być przechowywany w pamięci podręcznej w ramach wstępnej weryfikacji. Dzięki temu klient może wysyłać wiele złożonych żądań bez konieczności powtarzania żądania wstępnego.