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

Что такое CORS

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

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

Кратко

Скопировано

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

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

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

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

Как работает

Скопировано

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

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

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

Правильная настройка 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.1Host: api.example.comOrigin: doka.guide
          OPTIONS / HTTP/1.1
Host: api.example.com
Origin: doka.guide

        
        
          
        
      

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

        
          
          Access-Control-Allow-Origin: doka.guide
          Access-Control-Allow-Origin: doka.guide

        
        
          
        
      

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

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

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

        
        
          
        
      

Дополнительно можете задать маску:

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

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

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

Скопировано

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

Не забывайте регулярно заглядывать в настройки CORS и обновлять их.