[Разработка веб-сайтов, JavaScript, Программирование] Политика общего происхождения и CORS: визуальное руководство (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
11-Авг-2020 15:31


Доброго времени суток, друзья!
Представляю вашему вниманию перевод статьи «CS Visualized: CORS» автора Lydia Hallie.
Каждому разработчику приходилось сталкиваться с ошибкой Access to fetched has been blocked by CORS policy. Существует несколько способов быстрого решения данной проблемы. Однако, давайте не будем спешить и подробно рассмотрим, что из себя представляет политика CORS.
У нас часто возникает необходимость отобразить данные, находящиеся в другом месте. Прежде чем мы сможем это сделать, браузер должен отправить запрос на сервер, чтобы получить эти данные.
Допустим, мы хотим получить информацию о пользователе на нашем сайте www.mywebsite.com с сервера, расположенного на сайте api.website.com.

Отлично! Мы только что отправили запрос на сервер и получили в ответ данные в формате JSON.
Теперь попробуем отправить аналогичный запрос на другой домен. Вместо того, чтобы отправлять запрос с www.mywebsite.com, отправим его с www.anotherdomain.com.

Что случилось? Мы отправили точно такой же запрос, но на этот раз браузер показывает какую-то ошибку.
Мы наблюдаем CORS в действии. Почему возникла данная ошибка и что она означает?
Политика общего происхождения
В вебе присутствует нечто под названием политика общего происхождения (далее — ПОП). По умолчанию мы имеем доступ только к тем ресурсам, которые находятся в том же источнике, что и источник нашего запроса. Например, мы можем загрузить изображение, находящееся в https://mywebsite.com/image1.png.
Источник является другим, когда он расположен в другом (под)домене, протоколе или порте.

Круто, но зачем нужна ПОП?
Предположим, что ее не существует, и вы случайно кликаете по вирусной ссылке, которую прислала ваша тетя в Facebook. Данная ссылка перенаправляет вас на «вредоносный сайт», имеющий встроенный iframe, который загружает сайт вашего банка и успешно авторизуется там с помощью куки.
Разработчики «злого сайта» позаботились о том, чтобы он имел доступ к iframe и мог взаимодействовать с содержимым DOM сайта вашего банка для перечисления денежных средств на свой аккаунт от вашего имени.

Да уж… это серьезная проблема безопасности. Мы не хотим, чтобы кто-нибудь имел доступ к чему-либо без нашего ведома.
К счастью, существует ПОП. Эта политика ограничивает доступ к ресурсам из других источников.

В данном случае источник www.evilwebsite.com пытается получить доступ к ресурсу из источника www.bank.com. ПОП блокирует такой доступ и запрещает разработчикам «плохого сайта» доступ к вашим банковским данным.
Хорошо, но… как это работает?
CORS на стороне клиента
Несмотря на то, что ПОП применяется только к скриптам, браузеры «расширяют» ее до любых JavaScript-запросов: по умолчанию мы имеем доступ только к ресурсам из одного источника.

Хм, но… у нас часто возникает необходимость получить ресурсы из другого источника. Возможно, нашему фронтенду нужно обратиться к серверному прикладному интерфейсу для загрузки данных. Для безопасного получения ресурсов из других источников браузеры реализуют механизм под названием CORS.
CORS расшифровывается как Cross-Origin Resource Sharing (совместное использование ресурсов). Хотя браузеры запрещают получение ресурсов из других источников, мы можем использовать CORS для изменения этого ограничения, оставаясь при этом в безопасности.
Пользовательские агенты (браузеры) могут использовать механизм CORS для разрешения запросов между разными источниками, которые в противном случае были бы заблокированы, на основе некоторых заголовков HTTP-ответа.
Когда происходит запрос к другому источнику, клиент автоматически добавляет в HTTP-запрос заголовок Origin. Значением этого заголовка является источник запроса.

Для того, чтобы браузер разрешил получение ресурсов из другого источника, в ответе сервера также должен содержаться определенный заголовок.
CORS на стороне сервера
Как разработчики серверной части приложения, мы можем разрешить получение наших ресурсов другими источниками посредством включения в ответ специальных заголовков, начинающихся с Access-Control-*. На основе значения таких заголовков браузер разрешает совместное использование ресурсов.
Существует несколько CORS-заголовков, но один из них является обязательным: Access-Control-Allow-Origin.
Значение данного заголовка определяет, какие источники могут получать наши ресурсы.
Если мы разрабатываем сервер, который должен быть доступен https://mywebsite.com, мы должны добавить этот домен в заголовок Access-Control-Allow-Origin.

Здорово. Данный заголовок теперь добавляется к ответу сервера, отправляемого клиенту. ПОП больше не запрещает нам получать ресурсы с https://api.mywebsite.com с помощью запросов, отправленных с https://mywebsite.com.

Механизм CORS, реализованный в браузере, проверяет совпадение значений заголовка ответа Access-Control-Allow-Origin и заголовка запроса Origin.
В данном случае источником нашего запроса является https://www.mywebsite.com, указанный в списке заголовка ответа Access-Control-Allow-Origin.

Отлично. Теперь мы можем получать ресурсы из других источников. Что произойдет, если мы попытаемся сделать это из источника, не указанного в Access-Control-Allow-Origin?

Да, CORS заблокировал доступ к ресурсам.
The 'Access-Control-Allow-Origin' header has a value
  'https://www.mywebsite.com' that is not equal
to the supplied origin.

В данном случае источником является https://www.anotherwebsite.com, не указанный в Access-Control-Allow-Origin. CORS успешно запретил получение запрашиваемых данных.
CORS позволяет указать * в качестве значения разрешенных источников. Это означает, что ресурсы будут доступны любым источникам, так что будьте осторожны.
Access-Control-Allow-Origin — это один из многих заголовков, которые мы можем установить. Разработчик серверной части может настраивать CORS для разрешения (запрета) конкретных запросов.
Другим распространенным заголовком является Access-Control-Allow-Methods. CORS разрешает только те запросы из других источников, которые были отправлены с помощью указанных методов.

В данном случае разрешены только запросы, отправленные с помощью методов GET, POST или PUT. Другие методы, такие как PATCH или DELETE будут заблокированы.
Говоря о запросах, отправленных с помощью методов PUT, PATCH и DELETE, CORS обрабатывает их особым образом. Эти «непростые» запросы иногда называют предварительными (preflight).
Предварительные запросы
CORS работает с двумя типами запросов: простыми и предварительными. То, каким является запрос, зависит от некоторых его значений.
Запрос является простым, если он отправлен с помощью методов GET или POST и не содержит дополнительных заголовков. Любой другой запрос является предварительным.
Хорошо, но что означает предварительный запрос и зачем нужны такие запросы?
Перед отправкой фактического запроса, клиент направляет серверу предварительный запрос с информацией о фактическом запросе: о его методе, дополнительных заголовках, включая Access-Control-Request-* и т.д.

Сервер получает предварительный запрос и отправляет пустой предварительный ответ, содержащий CORS-заголовки. Браузер получает предварительный ответ и проверяет, будет ли разрешен фактический запрос.

Если да, то браузер отправляет фактический запрос и получает данные в ответ.

Если нет, CORS заблокирует предварительный запрос и фактический запрос не будет отправлен. Предварительные запросы — это отличный способ предотвратить доступ и изменение ресурсов на сервере. Это защищает сервер от потенциально нежелательных запросов из других источников.
Для уменьшения количества повторных запросов мы можем закэшировать предварительный ответ посредством добавления заголовка Access-Control-Max-Age в CORS-запрос. Это позволяет избежать повторного направления предварительного запроса.
Полномочия (credentials)
Куки, заголовки авторизации и сертификаты TLS по умолчанию устанавливаются только для запросов из одного источника. Однако у нас может возникнуть необходимость использовать эти полномочия в запросе из другого источника. Возможно, мы хотим включить в запрос куки, которые сервер может использовать для идентификации пользователя.
Хотя CORS не содержит полномочий по умолчанию, мы можем изменить это с помощью заголовка Access-Control-Allow-Credentials.
Если мы хотим включить куки и другие заголовки авторизации в наш запрос из другого источника, нам нужно присвоить полю withCredentials значение true в запросе и добавить заголовок Access-Control-Allow-Credentials в ответ.

Готово, теперь мы можем включать полномочия в наши запросы из другого источника.
Надеюсь, статья была вам полезной. Благодарю за внимание.
===========
Источник:
habr.com
===========

===========
Автор оригинала: Lydia Hallie
===========
Похожие новости: Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_programmirovanie (Программирование), #_javascript, #_programmirovanie (программирование), #_razrabotka (разработка), #_politika_obschego_proishozhdenija (политика общего происхождения), #_crossorigin_resource_sharing, #_cors, #_razrabotka_vebsajtov (
Разработка веб-сайтов
)
, #_javascript, #_programmirovanie (
Программирование
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 15-Май 07:39
Часовой пояс: UTC + 5