Bezpieczne udostępnianie zasobów z innych domen
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?
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ść.
Nagłówek
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
lubContent-Language
. - Żądanie, które ma nagłówek
Content-Type
inny niżapplication/x-www-form-urlencoded
,multipart/form-data
lubtext/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.