Клавиша / esc
Турист подходит к гробнице, а его встречает недовольный крылатый сфинкс
Иллюстрация: Кира Кустова

Что такое CORS

Определяем куда ходить можно, а куда нельзя.

Время чтения: меньше 5 мин

Кратко

Скопировано

CORS расшифровывается как Cross-Origin Resource Sharing. Это механизм браузера, который позволяет определить список ресурсов, к которым страница может получить доступ. Он необходим для обеспечения безопасности и защиты пользователей от злоумышленников при использовании HTTP протокола.

По умолчанию, сайты могут запрашивать ресурсы только со своего origin. Такое ограничение называется Same-Origin Policy. CORS расширяет Same-Origin Policy, позволяя получать доступ к ресурсам с разных доменов.

origin - это комбинация протокола, домена и порта (если он указан). Например, doka.guide - это домен, а https://doka.guide - origin.

Настройка доступа должна происходить как со стороны браузера, так и со стороны сервера.
Это означает, что и браузер, и сервер должны быть настроены на разрешение или запрет доступа к ресурсам с других origin.

Как работает

Скопировано

Рассмотрим пример работы CORS без дополнительной настройки:

Пользователь открывает страницу сайта doka.guide. Страница отправляет запрос к стороннему источнику api.example.com.
Браузер сравнивает origin и понимает, что api.example.com - сторонний origin для нашего сайта, из-за чего блокирует запрос. Причём запрос может быть заблокирован и в рамках одного домена, например у http://doka.guide и https://doka.guide origin будет отличаться из-за несовпадения протоколов.

Такие запросы с сайта на сайт называются перекрёстными.

Правильная настройка CORS помогает решить возможные проблемы с доступом к другим ресурсам и обеспечить безопасность веб-приложений.

Настройка

Скопировано

Для настройки CORS со стороны сервера используются специальные заголовки запроса:

  • Access-Control-Allow-Origin - указывает на origin, откуда на сервер разрешены запросы.
  • Access-Control-Allow-Methods - указывает, какие HTTP-методы разрешены для запросов на сервер. Например, GET, POST, DELETE.
  • Access-Control-Allow-Headers - определяет, какие заголовки могут быть использованы в ответе от сервера, которые не являются стандартными для HTTP.
  • Access-Control-Allow-Credentials - указывает, разрешено ли отправлять cookie и авторизационные данные вместе с запросом на сервер. Для разрешения используется значение true.
  • Access-Control-Max-Age - определяет максимальное время, в течение которого должны кэшироваться предыдущие ответы на запросы предварительной проверки CORS.
  • Access-Control-Expose-Headers - определяет список заголовков, которые могут быть доступны на клиентской стороне.

Также есть заголовок для настройки со стороны браузера:

  • Origin - указывает на комбинацию домена, порта и протокола, откуда на сервер поступает запрос.

И заголовки для настройки предварительных запросов:

  • Access-Control-Request-Method - определяет метод запроса, который будет использоваться в основном запросе.
  • Access-Control-Request-Headers - используется для указания заголовков, которые будут использоваться в основном запросе.

Предварительные запросы

Скопировано

Предварительный запрос - это дополнительный HTTP запрос, который отправляется браузером перед основным запросом.

Когда страница запрашивает данные с другого origin, браузер отправляет предварительный запрос OPTIONS на сервер, чтобы узнать, разрешены ли такие запросы. При повторном запросе на тот же origin, запрос OPTIONS может и не отправляться, а все данные будут получены из кеша.

При отправке запроса на api.example.com, браузер проставит заголовок Origin, сформирует запрос в определённом формате и отправит его на сервер:

OPTIONS / HTTP/1.1
Host: api.example.com
Origin: doka.guide

Если сервер запрещает доступ к ресурсу, то в результате запроса в браузере мы увидим ошибку.

А если доступ разрешён, то сервер ответит на запрос заголовком:

Access-Control-Allow-Origin: doka.guide

Такая запись означает, что сервер разрешает доступ с домена doka.guide.

Также можно разрешить доступ сразу для нескольких доменов. Тогда запись будет выглядеть так:

Access-Control-Allow-Origin: doka.guide github.com stackoverflow.com

Или задать маску:

  • *.site.com - для разрешения доступа с любого поддомена site.com.
  • * - для разрешения доступа отовсюду.

Однако необходимо быть осторожным при использовании этого заголовка, так как неправильная конфигурация может привести к уязвимостям безопасности. Например, если сервер отправляет Access-Control-Allow-Origin: *, это означает, что любой origin может получить доступ к ресурсам на сервере. Это может привести к возможности выполнения атак, например, CSRF и других.

Важно помнить

Скопировано

Настройка CORS происходит как со стороны браузера, так и со стороны сервера. Поэтому необходимо правильно настроить сервер, чтобы он возвращал нужные заголовки при запросах с других origin.