CORS: Какво е това и защо ни е необходимо?

Споделянето на ресурси между различни източници е протокол, който позволява на клиента от един източник да взаимодейства с ресурсите, намиращи се в различен произход. Когато казваме ресурси, това са неща като извиквания на API за извличане на някои данни, изтегляния на изображения, икони и т.н. Нуждаем се от CORS, за да презапише правилата за същия произход, последвана от XMLHttpRequest и fetch. Това означава, че Javascript може да извиква само URL адреси, които се хостват на същия произход (домейн) като този на самия скрипт. Въпреки това има много сценарии, когато бихме искали да използваме услугите, принадлежащи на друг домейн, и в такива сценарии cors би ни бил полезен.

Политика за същия произход

Браузърите прилагат механизъм за сигурност, наречен политика за същия произход. Тази политика е въведена за борба с една от най-разпространените кибератаки: фалшифициране на междусайтови заявки. По време на фалшифициране на заявка между сайтове злонамерен нападател/уебсайт се опитва да открадне системата за бисквитки на браузъра и да се опита да открадне ресурси в името на автентичен уебсайт.

Правила за бисквитки на браузъра: Всеки път, когато се направи HTTP заявка към домейн от браузъра, тя прикачва всяка бисквитка, която се съхранява в браузъра, свързана с този домейн. Това е полезно за удостоверяване и за установяване на сесията. Например: Когато влезете в https://example.com, сървърът ще зададе определени бисквитки, свързани със сесията, за домейна https://example.com в браузъра. Всеки път, когато посещавате отново https://example.com или извършвате API извиквания към https://example.com, сесийните бисквитки ще бъдат изпратени заедно със заявката. API ще разпознае тази бисквитка и ще позволи достъп без влизане отново и отново.

Тъй като браузърът автоматично прикачва всички съответни бисквитки на домейн по време на всяка заявка, злонамерен уебсайт ще се опита да изпрати заявки до https://example.com от браузъра. При такъв сценарий бисквитките, съхранени в браузъра за домейна https://example.com, ще бъдат изпратени. Ако бисквитките са валидни, злонамереният уебсайт получава достъп до https://example.com и неговите ресурси. По този начин акаунтът на потребителя ще бъде подложен на атака за фалшифициране на междусайтови заявки.

За да предотвратят това, браузърите са внедрили политиката за същия произход. Това означава, че всички заявки, направени от браузъра от даден уебсайт към същия домейн, ще бъдат разрешени. Той ще спре заявките, идващи от различен домейн съгласно правилата same-origin.

Защо браузърите издават CORS грешка? Знаем, че заявките от различни източници обикновено се блокират от браузърите поради съображения за сигурност. Уеб сървърът не само съдържа публично достъпни активи като изображения и шрифтове, но също така съдържа чувствителна информация като лична информация на потребител. Тези уеб сървъри понякога предоставят публично достъпни API за други уебсайтове, които да използват и взаимодействат с техните ресурси. Това може да е форма на услуга, предоставяна от един сървър на друг. Следват няколко причини, поради които заявките от кръстосан произход обикновено се блокират от браузърите:

  • Исканият API не позволява споделяне на ресурси от различни източници
  • Изложеният API позволява на определени квалифицирани домейни да изпращат споделяне на ресурси от кръстосан произход
  • Приложният програмен интерфейс (API) изисква да бъдат изпратени определени заглавки, за да позволи споделяне на ресурси от различни източници

CORS грешки и начини за разрешаването им

Ако сте се занимавали с уеб разработка за известно време, сигурен съм, че трябва да сте срещали следната грешка:

Всеки път, когато се опитвате да работите с външни API, може да сте се сблъсквали с тази грешка. Може също да сте опитали да изпратите заглавки като 'Access-Control-Allow-Headers': '*', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Credentials': true заедно със заявката и да не сте успели да разрешите грешката CORS:

През повечето време тази грешка може да бъде разрешена чрез добавяне на определени заглавки като Access-Control-Allow-Origin: "https://example.com". Това по същество означава, че API сървърът, хостван в различен домейн, се доверява на нашия домейн и е готов да сподели своите ресурси. Приложните програмни интерфейси (API) са изградени за обща цел и API не могат да започнат да поставят в белия списък всеки нов домейн, който се появява в интернет. Освен това няма гаранция, че домейнът, който е установил доверието днес, няма да стане злонамерен утре.

И така, какво да правя сега? Отказваме ли се? Какви са начините за разрешаване на този проблем?

Има няколко начина, по които грешката на cors може да бъде разрешена:

1. Инсталиране на добавки Allow-origin в браузъра:

Ако само тествате API и искате да използвате неговите данни, без да се занимавате с проблема с CORS, възможно е да инсталирате приставката CORS и да правите API извиквания от браузъра, сякаш изисква ресурсите от същия домейн. Имайте предвид, че приставката е само корекция във вашата локална машина. Приставката по същество ще добави Access-Control-Allow-Origin: * заглавка към отговора, идващ от кръстосания сървър, и ще подмами браузъра да позволи на заявката да премине.

2. Използвайте прокси на трета страна:

Заявките, идващи от нашия браузър, могат да бъдат изпратени през прокси сървър, който прикачва Access-Control-Allow-Origin: * заглавка към всеки отговор, който изпраща обратно. Сървърът cors-anywhere действа като междинен прокси между клиента и сървъра.

В този случай, ако искате да поискате до https://example.com, заявката ще бъде изпратена до https://cors-anywhere.herokuapp.com/, заедно с информацията за оригиналния сървър, който искам да ударя. Това решение е чудесен случай за използване, когато не искаме да се натоварваме с каквото и да е бекенд програмиране. Ще използваме cors-anywhere и ще превърнем заявката (браузър-сървър) в заявка (сървър-сървър).

3. Изградете прокси сървър.

Един от проблемите при използването на прокси сървър на трета страна е зависимостта. Не можем да потвърдим неговата наличност и мащабируемост. Също така не можем да му се доверим напълно и да изпратим клиентски тайни на прокси сървъра. По-добър подход е да се изгради прокси сървър и да се хоства заедно с кодовата база на интерфейса. По този начин заявките първо ще бъдат отправени към нашия сървър, намиращ се в същия домейн, и след това ще бъдат препратени от нашия сървър към https://example.com. Това ще установи комуникация (сървър-сървър) и заявката ще бъде изпълнена.

Грешките в CORS могат да бъдат обезпокоителни за разработчиците от предния край, особено когато нямаме никакви познания относно бекенда. В случай на прости приложения, можем да използваме прокси сървъри на трети страни и да изпълним нашите заявки.