Понимание CORS
Правило одного источника является важным принципом обеспечения безопасности, реализованное web браузерами для предотвращения выполнения JavaScript кодом запросов к другим источникам(т.е. к другим доменам), а не к тому, с которого он передан. Несмотря на эффективность такого правила, оно также ограничивает в законных взаимодействиях между сервером и клиентами из надежных источников.
Cross-Origin Resource Sharing (CORS) является техникой для ослабления правила одного источника, позволяя JavaScript на web странице обрабатывать ответ от REST API от другого источника.
Обработка простых CORS запросов
В простейшем случае, междоменные взаимодействия начинаются с запроса GET, POST или HEAD к ресурсу
на сервере. В данном случае, тип содержимого POST запроса ограничен application/x-www-form-urlencoded
,
multipart/form-data
или text/plain
. Запрос включает заголовок Origin
,
который указывает на происхождение клиентского кода.
Сервер будет учитывать Origin
запроса и принимать или отказывать в обработке запроса.
Если сервер принял запрос, то он ответит запрашиваемым ресурсом в заголовке
Access-Control-Allow-Origin
. Этот заголовок будет указывать клиенту с каким происхождением
клиента будет разрешен доступ к ресурсу. Принимая во внимание, что Access-Control-Allow-Origin
соответствует Origin
запроса, браузер разрешит запрос.
С другой стороны, если Access-Control-Allow-Origin
отсутствует в ответе или
если его нет в Origin
запроса, то браузер не разрешит запрос.
К примеру, предположим, что клиентский код расположен на foo.client.com и отправляет запрос на bar.server.com:
GET /greeting/ HTTP/1.1 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1 Accept: application/json, text/plain, */* Referer: http://foo.client.com/ Origin: http://foo.client.com
Заголовок Origin
говорит серверу, что клиентский код создан в http://foo.client.com.
Так он проверяет правила одного источника и определяет, что он может обработать запрос. Ответ
может выглядеть примерно так:
HTTP/1.1 200 OK Content-Type: application/json;charset=UTF-8 Date: Wed, 20 Nov 2013 19:36:00 GMT Server: Apache-Coyote/1.1 Content-Length: 35 Connection: keep-alive Access-Control-Allow-Origin: http://foo.client.com [response payload]
Access-Control-Allow-Origin
указывает на то, что "http://foo.client.com"
разрешен доступ, но не другим источникам.
Дополнительно Access-Control-Allow-Origin
может быть установлен в "*",
указывая на доступность всем. Это считается небезопасной практикой, кроме тех особых
случаев, где API полностью публично и предназначено для использования любым клиентом.
Предполетные запросы
Если запрос может оказать влияние на пользовательские данные, то простого запроса
недостаточно. Вместо этого, предполентый CORS запрос отправляется в перед отправкой
необходимого запроса, чтобы гарантировать безопасность отправки запроса. Предполетные
запросы необходимы в тех случаях, когда любой HTTP метод, отличный от GET, POST, HEAD
или если тип содержимого POST запроса отличен от application/x-www-form-urlencoded
,
multipart/form-data
или text/plain
. Также, если запрос содержит
любые собственные заголовки, то необходим предполетный запрос.
К примеру, предположим, что клиент, расположенный на foo.client.com, выполняет DELETE запрос к ресурсу не bar.server.com. Предполетный запрос принимает вид OPTIONS запроса со следующими заголовками:
OPTIONS /resource/12345 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1 Access-Control-Request-Method: DELETE Access-Control-Request-Headers: origin, x-requested-with, accept Origin: http://foo.client.com
Предполетный запрос фактически спрашивает сервер о доступности DELETE запроса без фактической отправки самого DELETE запроса. Если сервер разрешает такой запрос, то он ответит предполетному запросу примерно так:
HTTP/1.1 200 OK Date: Wed, 20 Nov 2013 19:36:00 GMT Server: Apache-Coyote/1.1 Content-Length: 0 Connection: keep-alive Access-Control-Allow-Origin: http://foo.client.com Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE Access-Control-Max-Age: 86400
Ответ предполетному запросу указывает(в заголовке Access-Control-Allow-Methods
)
на то, что клиенту доступен DELETE запрос к передаваемому ресурсу. Заголовок
Access-Control-Max-Age
указывает на то, что этот предполетный ответ действует
84600 секунд или 1 день, после которого должен быть выполнен новый предполетный запрос.
В то же время клиенту будет доступно отправка настоящего DELETE запроса к ресурсу.
С оригинальным текстом урока вы можете ознакомиться на spring.io.
comments powered by Disqus