Letysite.ru

IT Новости с интернет пространства
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Access control request headers

fastcodenote

Страницы

вторник, 11 февраля 2014 г.

CORS. Как посылать запросы GET, POST, DELETE etc.

В наши дни не знать что такое CORS (wiki), сродни прогулки тёмной ночью по последнему этажу, недостроенной высотки где-нибудь за городом, в неблагополучном районе. Т.е. смертеподнобно, а особенно если вы фронт-енд разработчик.

Более подробно вы можете ознакомиться перейдя по ссылкам в конце текста, я же скажу вкратце, CORS это набор HTTP заголовков, которые позволяют объяснить браузеру и серверу, что они хоть и из разных доменов, но одной крови работать могут вместе. Т.е. кросс-доменные зпросы поддерживаються. Кто не знает, то запрос из браузера посредством старого, доброго JavaSctipt недавно, так на чистоту, без костылей сделать было невозможно. Ура, эти мрачные времена канули в лету. Пришёл на момощь CORS.

Речь пойдет именно о процессе использования и базовой настройки заголовков сервера, и отсыла запросов клиента с использованием jQuery.

Сервер, который мнит себя крутым сервисом, настолько куртым что хочет предоставить поддержку кросс-доменных запросов. Должен клинету сообщить об этом. Отправив следующие заголовки:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers

Это тот минимум, который необходим для успешной работы наших кросс-доменных запросов. немного рапишем что, к чему:

Access-Control-Allow-Origin — (обязательный) собственно список разделенный пробелами допустимых доменнов (источников), которые будут ломиться делать запросы к нам на сервер. Из особенностей: регистрозависим, поддерживает маски, например, http://api.superservice.com/, http://*.superservice.com/ или, как вы могли догадаться просто «звездочка» *. Этот заголовок будет сравниваться с заголовком Origin клиентского запроса.
Access-Control-Allow-Method — (обязательный) это список доступных HTTP методов, разделенных запятыми. Особое внимание стоит уделить тому, что «звездочка» аля * работать не будет!
Access-Control-Allow-Headers — (обязательный вместе с Access-Control-Request-Headers) список через запятую заголовков разрешенных в запросе.

Пример настройки для Apache:

Давайте разберемся, что тут происходит? А происходит следующее, запросы будут обработанны с любого источника, если они будут одного из перечисленных в Header always set Access-Control-Allow-Methods типов, так же будут подерживаться заголовки X-Requested-With и content-type

Тот же пример для PHP

Теперь, предположим, что сервис у нас крутится по адресу http://api.superservice.com/ , а GET запрос нам надо сделать со странички http://pure.client.net/. Это не сложно сделать, к примеру с jQuery:

Думаю самое время упомянуть о неприятном моменте с AngularJs если вам понадобиться сделать кросс-доменый запрос с помощью $http или $resource, то надо будет удалить один заголовок, делается это так:

Такое поведение странно, для меня, по крайней мере, несмотря на то что заголовок X-Requested-With вы укажите Access-Control-Allow-Headers не исключены проблемы с запросами. Ходят слухи что это бага AngularJs, кому интересно, если найдете что, отпишитесь в коментах.

Переходим к интересным запросам типа POST/PUT/DELETE, всех их объединяет то что они пытаются что-то изменить на сервере. Но как сделать такой запрос кросс-доменным? Сначала надо получить список заголовков типа Access-Control-*, делается это предварительным OPTIONS запросом. Который может вернуть тот же набор Access-Control-*, что и обычный метод GET.

На сервере если вы больше нигде и не для чего более не будете использовать OPTIONS запросы, то можете смело на все запросы типа OPTIONS отвечать необходимыми заголовками в том числе и такими заветными для нас как CORS заголовки. Если кто не понял то имееться ввиду добавить правило для всех запросов типа OPTIONS в роутах вашего любимого фреймворка. Или же сделать обработку руками.

Этот предварительный запрос (prefligth-запрос), делается автоматически jQuery или тем же Angular, по-тому же URL что и ваш основной запрос POST/PUT/DELETE поэтому будте внимательны если вы не сделаете правильной обработку запросов типа OPTIONS то и запрос POST/PUT/DELETE у вас сделать не получиться, из-за политики безопасности, который следуют браузеры.

Пример запроса POST с использованием jQuery.

Я старался изложить кратко, в справочном виде, не очень получилось :), но думаю многим кто прочитал это сэкономит время. Ниже список источников, который позволят вам более глумого изучить вопрос CORS

XMLHttpRequest: кросс-доменные запросы

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/fetch-crossorigin.

Обычно запрос XMLHttpRequest может делать запрос только в рамках текущего сайта. При попытке использовать другой домен/порт/протокол – браузер выдаёт ошибку.

Существует современный стандарт XMLHttpRequest, он ещё в состоянии черновика, но предусматривает кросс-доменные запросы и многое другое.

Большинство возможностей этого стандарта уже поддерживаются всеми браузерами, но увы, не в IE9-.

Впрочем, частично кросс-доменные запросы поддерживаются, начиная с IE8, только вместо XMLHttpRequest нужно использовать объект XDomainRequest.

Кросс-доменные запросы

Разберём кросс-доменные запросы на примере кода:

  1. Мы создаём XMLHttpRequest и проверяем, поддерживает ли он событие onload . Если нет, то это старый XMLHttpRequest , значит это IE8,9, и используем XDomainRequest .
  2. Запрос на другой домен отсылается просто указанием соответствующего URL в open . Он обязательно должен быть асинхронным, в остальном – никаких особенностей.

Контроль безопасности

Кросс-доменные запросы проходят специальный контроль безопасности, цель которого – не дать злым хакерам™ завоевать интернет.

Серьёзно. Разработчики стандарта предусмотрели все заслоны, чтобы «злой хакер» не смог, воспользовавшись новым стандартом, сделать что-то принципиально отличное от того, что и так мог раньше и, таким образом, «сломать» какой-нибудь сервер, работающий по-старому стандарту и не ожидающий ничего принципиально нового.

Давайте, на минуточку, вообразим, что появился стандарт, который даёт, без ограничений, возможность делать любой странице HTTP-запросы куда угодно, какие угодно.

Как сможет этим воспользоваться злой хакер?

Он сделает свой сайт, например http://evilhacker.com и заманит туда посетителя (а может посетитель попадёт на «злонамеренную» страницу и по ошибке – не так важно).

Когда посетитель зайдёт на http://evilhacker.com , он автоматически запустит JS-скрипт на странице. Этот скрипт сделает HTTP-запрос на почтовый сервер, к примеру, http://gmail.com . А ведь обычно HTTP-запросы идут с куками посетителя и другими авторизующими заголовками.

Поэтому хакер сможет написать на http://evilhacker.com код, который, сделав GET-запрос на http://gmail.com , получит информацию из почтового ящика посетителя. Проанализирует её, сделает ещё пачку POST-запросов для отправки писем от имени посетителя. Затем настанет очередь онлайн-банка и так далее.

Спецификация CORS налагает специальные ограничения на запросы, которые призваны не допустить подобного апокалипсиса.

Запросы в ней делятся на два вида.

Простыми считаются запросы, если они удовлетворяют следующим двум условиям:

  1. Простой метод: GET, POST или HEAD
  2. Простые заголовки – только из списка:
  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type со значением application/x-www-form-urlencoded , multipart/form-data или text/plain .

«Непростыми» считаются все остальные, например, запрос с методом PUT или с заголовком Authorization не подходит под ограничения выше.

Принципиальная разница между ними заключается в том, что «простой» запрос можно сформировать и отправить на сервер и без XMLHttpRequest, например при помощи HTML-формы.

То есть, злой хакер на странице http://evilhacker.com и до появления CORS мог отправить произвольный GET-запрос куда угодно. Например, если создать и добавить в документ элемент

Комментарии

  • Если вам кажется, что в статье что-то не так — вместо комментария напишите на GitHub.
  • Для одной строки кода используйте тег , для нескольких строк кода — тег
Читать еще:  Java nio file accessdeniedexception

, если больше 10 строк — ссылку на песочницу (plnkr, JSBin, codepen…)

  • Если что-то непонятно в статье — пишите, что именно и с какого места.
  • тут блог

    Общественные обязательства интроверта.
    Сообщения на ИТ тематику, но не обязательно.

    О CORS

    Современные браузеры не хотят просто так ходить на другие домены. Точнее на другой Origin. Это касается JavaScript, выполняемого в браузере.

    Нельзя просто так взять, и потыкать API, находящееся в другом домене. И нельзя сделать crawler, работающий в браузере. Это будут cross-origin запросы. И они запрещены. Из соображений безопасности. Похоже, это скорее забота о том, чтобы конфиденциальные данные из вашего браузера не утекли куда не надо, чем попытка затруднить жизнь тем, кто захочет воспользоваться вашим API.

    Но иногда у вас какой-нибудь SPA на React должен ходить в API на другой домен. И тут на помощь приходит CORS. Cross-Origin Resource Sharing. Сервер другого ресурса, нашего API, может явно сказать, с каких Origin к нему разрешён доступ. С помощью некоторых дополнительных HTTP заголовков.

    В простейшем случае, когда наш JavaScript делает GET запрос, и не передаёт никаких потенциально опасных заголовков, браузер включает в запрос заголовок Origin . А сервер должен ответить с заголовком Access-Control-Allow-Origin , где, собственно, и говорит, разрешён ли доступ с этого Origin.

    В более сложном случае, например, когда мы делаем POST запрос с JSON в теле запроса, браузер делает так называемый «preflight request».

    Это OPTIONS запрос, в который включены заголовки, описывающие будущий полноценный запрос. Access-Control-Request-Method говорит, какой HTTP метод будет в будущем запросе. Access-Control-Request-Headers говорит, какие HTTP заголовки будут в будущем запросе (помимо тех, вроде Host , User-Agent и Acept , которые и так разрешены по умолчанию). Конечно же, этот запрос включает заголовок Origin .

    Если сервер согласен и с Origin, и с методом, и с заголовками, он отвечает 200 OK с дополнительными заголовками. Снова заголовок Access-Control-Allow-Origin выражает согласие сервера с Origin. Заголовок Access-Control-Allow-Methods перечисляет методы, которые сервер готов принимать с этого Origin. Заголовок Access-Control-Allow-Headers подтверждает готовность сервера принимать заголовки. Заголовок Access-Control-Max-Age указывает срок действия данного соглашения, браузер может какое-то время не повторять preflight запросы.

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

    По умолчанию credentials запрещены. Но сервер может разрешить, если выдаст заголовок Access-Control-Allow-Credentials со значением true . Но для Origin «*» это не работает.

    Если говорить про fetch() в браузере, то для credentials есть свои опции.

    Сервер может ещё использовать заголовок Vary , чтобы указать на заголовки запроса, изменение которых приведёт к другому ответу сервера. Поэтому положено, если Access-Control-Allow-Origin возвращает конкретный Origin, то должен быть ещё и Vary: Origin .

    Почти во всех случаях, когда у вас есть SPA и отдельное API, вам придётся учитывать CORS.

    Вам повезло, если вы можете закрыть и фронтенд и бэкенд общим прокси на одном домене. Тогда ваше API будет, скажем, просто по относительному URL «/api», и это будет same-origin, и CORS не понадобится.

    Вам повезло, если перед бэкендом вы можете поставить прокси, которое сможет добавлять заголовки. Например, Nginx. Тогда он сможет взять на себя всю работу c CORS. Не забудьте включить в Access-Control-Allow-Headers все заголовки, которые рожает ваше SPA.

    Если вам позарез нужны credentials, например, аутентификация у вас через cookie, то всё немного усложняется.

    Как правило, на preflight запрос сервер должен отвечать минуя все механизмы авторизации. Собственно, так и произойдёт, если вы к этому location добавите ещё, например, директивы auth_basic . Потому что return прерывает обработку запроса раньше.

    Приведённые конфигурации открывают доступ к API с любого Origin. Возможно, это не то, что вы хотите. Тогда разбираться с CORS придётся в самом бэкенде.

    Если вы разворачиваетесь в облаке, то вряд ли вам захочется запускать свой Nginx, лучше воспользоваться облачным load balancer. А они вовсе не обязаны втыкать дополнительные заголовки. К тому же в облаках статику и динамику как-то удобнее размещать в разных доменах, CDN, всё такое. Так что от CORS не отвертитесь, и снова на бэкенде.

    3 Ways to Fix the CORS Error — and How the Access-Control-Allow-Origin Header Works

    The Cors Error

    Seen this before? Seeing it right now?

    When working with APIs in your application code, honestly, this bug creeps up more often than it should. And every time, the reaction is the same:

    Fix one: install the Allow-Control-Allow-Origin plugin

    The quickest fix you can make is to install the moesif CORS extension . Once installed, click it in your browser to activate the extension. Make sure the icon’s label goes from “off”:

    Then refresh your application, and your API requests should now work!

    But the plugin fix is deceiving

    The plugin definitely addresses the issue. However, this fix only applies to your own machine. In local development, it’s fine to have a plugin installed that can help you get past the error.

    But once you publish your application, you can’t expect your users to install the plugin too. It wouldn’t be the wisest business decision…

    There’s gotta be better solutions. To get there, let’s answer a couple questions:

    Why was the CORS error there in the first place?

    The error stems from a security mechanism that browsers implement called the same-origin policy.

    The same-origin policy fights one of the most common cyber attacks out there: cross-site request forgery. In this maneuver, a malicious website attempts to take advantage of the browser’s cookie storage system.

    For every HTTP request to a domain, the browser attaches any HTTP cookies associated with that domain. This is especially useful for authentication, and setting sessions. For instance, it’s feasible that you would sign into a web app like facebook-clone.com. In this case, your browser would store a relevant session cookie for the facebook-clone.com domain:

    And this is great! The session cookie gets stored. And every time you re-visit the facebook-clone.com tab, and click around the app, you don’t have to sign in again. Instead, the API will recognize the stored session cookie upon further HTTP requests.

    The only trouble is that the browser automatically includes any relevant cookies stored for a domain when another request is made to that exact domain. Therefore, a scenario like this can happen. Say you clicked on a particularly trick popup add, opening evil-site.com.

    Читать еще:  Point in time

    The evil site also has the ability send a request to facebook-clone.com/api. Since the request is going to the facebook-clone.com domain, the browser includes the relevant cookies. Evil-site sends the session cookie, and gains authenticated access to facebook-clone. Your account has been successfully hacked with a cross-site request forgery attack.

    Luckily, in this situation, like a hawk ready to strike, the browser will step in and prevent the malicious code from making an API request like this. It will stop evil-site and say “Blocked by the same-origin policy. ️”

    How does the same-origin policy work under the hood?

    Under the hood, the browser checks if the origins of the web application and the server match. Above, the origins were simplified to the frontend application and backend server domains. But really, the origin is the combination of the protocol, host, and port. For example, in https://www,facebook-clone.com, the protocol is https://, the host is www.facebook-clone.com, and the hidden port number is 443 (the port number typically used for https).

    To conduct the same-origin check, the browser accompanies all requests with a special request that sends the domain information receiving server. For example, for an app running on localhost:3000, the special request format looks like this:

    Reacting to this special request, the server sends back a response header. This header contains an Access-Control-Allow-Origin key, to specify which origins can access the server’s resources. The key will have one of two values:

    One: the server can be really strict, and specify that only one origin can access it:

    Two: the server can let the gates go wide open, and specify the wildcard value to allow all domains to access its resources:

    Once the browser receives this header information back, it compares the frontend domain with the Access-Control-Allow-Origin value from the server. If the frontend domain does not match the value, the browser raises the red flag and blocks the API request with the CORS policy error.

    Did the plugin “fix” it?

    In short, no. The access-control-allow-origin plugin essentially turns off the browser’s same-origin policy. For every request, it will add the Access-Control-Allow-Origin: * header to the response. It tricks the browser, and overrides the CORS header that the server has in place with the open wildcard value.

    Now, it’s fine to leave this plugin on in local development. It’s possible that you already know that the server specifies the Access-Control-Allow-Origin header as the published frontend domain for your app. Then by all means, use the plugin in development to allow the localhost domain to make requests within the browser.

    But if you’re consuming another API, the plugin hasn’t “fixed” the issue. As mentioned before, you wouldn’t want to demand that your users install a plugin to access your code.

    Fix two: send your request to a proxy

    You can’t ask your users to trick their browsers by installing a plugin that applies an header in the frontend. But you can control the backend address that the web app’s API requests are going to.

    The cors-anywhere server is a proxy that adds CORS headers to a request. A proxy acts as an intermediary between a client and server. In this case, the cors-anywhere proxy server operates in between the frontend web app making the request, and the server that responds with data. Similar to the Allow-control-allow-origin plugin, it adds the more open Access-Control-Allow-Origin: * header to the response.

    It works like this. Say your frontend is trying to make a GET request to:

    But this api does not have a Access-Control-Allow-Origin value in place that permits the web application domain to access it. So instead, send your GET request to:

    The proxy server receives the https://joke-api-strict-cors.appspot.com/jokes/random from the url above. Then it makes the request to get that server’s response. And finally, the proxy applies the Access-Control-Allow-Origin: * to that original response.

    This solution is great because it works in both development and production. In summary, you’re taking advantage of the fact that the same origin policy is only implemented in browser-to-server communication. Which means it doesn’t have to be enforced in server-to-server communication!

    The one downside of the cors-anywhere proxy is that can often take a while to receive a response. The latency is high enough to make your applications appear a bit sluggish.

    This brings us to a final, even better approach.

    Fix three: build your own proxy

    The fix I recommend in situations like this, is to build your own proxy! Exactly like the previous solution, you’re utilizing the fact that the same origin policy is not enforced within server-to-server communication. In addition, you eliminate the latency concern. You don’t need to share the cors-anywhere proxy with other consumers, and you can dedicate as many resources as you need to your own servers.

    Here’s some quick Node.js code that uses the express web framework to create a proxy server around the same https://joke-api-strict-cors.appspot.com/ from above:

    How does this work? The proxy uses express middleware to apply a Access-Control-Allow-Origin: * header to every response from the server. At its own jokes/random GET endpoint, the proxy requests a random joke from another server. The same-origin policy doesn’t step in to block the request, even though the domains are different. After all, this is a server-to-server request. Finally, the proxy creates a response to the original requester (an app on the browser) consisting of the resulting data and the middleware-applied Access-Control-Allow-Origin: * header.

    Conclusion

    The CORS error can be the bane of the frontend developer. But once you understand the underlying same-origin policy behind the error, and how it fights the malicious cross-site request forgery attack, it becomes a little more bearable.

    Ultimately, with these fixes, you’ll never have to break a sweat over seeing that red CORS error in your browser console logs again. Instead, in its face, you’ll whip out the plugin or a proxy, and exclaim:

    Что такое CORS

    Многие из нас встречались с подобной ошибкой:

    Access to XMLHttpRequest at ‘XXXX’ from origin ‘YYYY’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource..

    Эта статья рассказывает что означает эта ошибка и как от нее избавиться.

    Создадим тестовый сайт на Node.js с открытым API и запустим его по адресу http://127.0.0.1:3000.

    Пусть там будет примерно такая функция получения GET запроса:

    Читать еще:  Module entry point

    Пусть там будет простая функция входа в систему, где пользователи вводят общее секретное слово secret и им затем ему устанавливается cookie, идентифицируя их как аутентифицированных:

    И пусть у нас будет некое приватное API для каких нибудь личных данных в /private, только для аутентифицированных пользователей.

    Запрос нашего API через AJAX из других доменов

    И допустим у нас есть какое-нибудь клиентское приложение работающее с нашим API. Но учтем что, наше API находится по адресу http://127.0.0.1:3000/public, а наш клиент размещен на http://127.0.0.1:8000, и на клиенте есть следующий код:

    И это не будет работать!

    Если мы посмотрим на вкладку network в консоле Хрома при обращение c http://127.0.0.1:8000 к http://127.0.0.1:3000 то там не будет ошибок:

    Сам по себе запрос был успешным, но результат оказался не доступен. Описание причины можно найти в консоли JavaScript:

    Ага! Нам не хватает заголовка Access-Control-Allow-Origin. Но зачем он нам и для чего он вообще нужен?

    Same-Origin Policy

    Причиной, по которой мы не получим ответ в JavaScript, является Same-Origin Policy. Эта ограничительная мера была придумана разработчиками браузеров что бы веб-сайт не мог получить ответ на сгенерированный AJAX запрос к другому веб-сайту находящемуся по другому адресу .

    Например: если вы заходите на sample.org, вы бы не хотели, чтобы этот веб-сайт отправлял запрос к примеру на ваш банковский веб-сайт и получал баланс вашего счета и транзакции.

    Same-Origin Policy предотвращает именно это.

    «источник (origin)» в этом случае состоит из

    • протокол (например http )
    • хост (например example.com )
    • порт (например 8000 )

    Так что http://sample.org и http://www.sample.org и http://sample.org:3000 – это три разных источника.

    Пару слов о CSRF

    Обратите внимание, что существует класс атак, называемый подделкой межсайтовых запросов (Cross Site Request Forgerycsrf ), от которых не защищает Same-Origin Policy.

    При CSRF-атаке злоумышленник отправляет запрос сторонней странице в фоновом режиме, например, отправляя POST запрос на веб-сайт вашего банка. Если у вас в этот момент есть действительный сеанс с вашим банком, любой веб-сайт может сгенерировать запрос в фоновом режиме, который будет выполнен, если ваш банк не использует контрмеры против CSRF.

    Так же обратите внимание, что, несмотря на то, что действует Same-Origin Policy, наш пример запроса с сайта secondparty.com на сайте 127.0.0.1:3000 будет успешно выполнен – мы просто не соможем получить доступ к результатам. Но для CSRF нам не нужен результат …

    Например, API, которое позволяет отправлять электронные письма, выполняя POST запрос, отправит электронное письмо, если мы предоставим ему правильные данные. Злоумышленнику не нужно заботится о результате, его забота это отправляемое электронное письмо, которое он получит независимо от возможности видеть ответ от API.

    Включение CORS для нашего публичного API

    Допустим нам нужно разрешить работу JavaScript на сторонних сайтах (например, 127.0.0.1:8000) что бы получать доступ к нашим ответам API. Для этого нам нужно включить CORS в заголовок ответа от сервера. Это делается на стороне сервера:

    Здесь мы устанавливаем заголовку Access-Control-Allow-Origin значение *, что означает: что любому хосту разрешен доступ к этому URL и ответу в браузере:

    Непростые запросы и предварительные запросы (preflights)

    Предыдущий пример был так называемым простым запросом. Простые запросы – это:

    • Запросы: GET,POST
    • Тип содержимого следующего:
      • text/plain
      • application/x-www-form-urlencoded
      • multipart/form-data

    Допустим теперь 127.0.0.1:8000 немного меняет реализацию, и теперь он обрабатывает запросы в формате JSON:

    Но это снова все ломает!
    На этот раз консоль показывает другую ошибку:

    Любой заголовок, который не разрешен для простых запросов, требует предварительного запроса (preflight request).

    Этот механизм позволяет веб-серверам решать, хотят ли они разрешить фактический запрос. Браузер устанавливает заголовки Access-Control-Request-Headers и Access-Control-Request-Method, чтобы сообщить серверу, какой запрос ожидать, и сервер должен ответить соответствующими заголовками.

    Но наш сервер еще не отвечает с этими заголовками, поэтому нам нужно добавить их:

    Теперь мы снова может получить доступ к ответу.

    Credentials и CORS

    Теперь давайте предположим, что нам нужно залогинится на 127.0.0.1:3000 что бы получить доступ к /private с конфиденциальной информацией.

    При всех наших настройках CORS может ли другой сайт так же получить эту конфиденциальную информацию?

    Мы пропустили код реализации входа в на сервер так как он не обязателен для объяснения материала.

    Независимо от того, попытаемся ли мы залогинится на 127.0.0.1:3000 или нет, мы увидим «Please login first».

    Причина в том, что cookie от 127.0.0.1:3000 не будут отправляться, когда запрос поступает из другого источника. Мы можем попросить браузер отправить файлы cookie клиенту, даже если запрос с других доменов:

    Но опять это не будет работать в браузере. И это хорошая новость, на самом деле.

    Итак, мы не хотим, чтобы злоумышленник имел доступ к приватным данным, но что, если мы хотим, чтобы 127.0.0.1:8000 имел доступ к /private?
    В этом случае нам нужно установить для заголовка Access-Control-Allow-Credentials значение true:

    Но это все равно пока еще не сработает. Это опасная практика – разрешать любые аутентифицированные запросы с других источников.

    Браузер не позволит нам так легко совершить ошибку.

    Если мы хотим разрешить 127.0.0.1:8000 доступ к /private, нам нужно указать точный источник в заголовке:

    Теперь http://127.0.0.1:8000 также имеет доступ к приватным данным, в то время как запрос с любого другого сайта будет заблокирован.

    Разрешить множественные источники (origin)

    Теперь мы разрешили одному источнику делать запросы к другому источнику с данными аутентификации. Но что, если у нас есть несколько других источников?

    В этом случае мы, вероятно, хотим использовать белый список:

    Опять же: не отправляйте напрямую req.headers.origin в качестве разрешенного заголовка CORS. Это позволит любому веб-сайту получить доступ к приватным данным.
    Из этого правила могут быть исключения, но, по крайней мере, дважды подумайте, прежде чем внедрять CORS с учетными данными без белого списка.

    Заключение

    В этой статье мы рассмотрели Same-Origin Policy и то, как мы можем использовать CORS, чтобы разрешать запросы между источниками, когда это необходимо.

    Это требует настройки на стороне сервера и на стороне клиента и в зависимости от запроса вызовет предварительный (preflight) запрос.

    При работе с аутентифицированными запросами перекрестного происхождения следует проявлять дополнительную осторожность. Белый список может помочь разрешить нескольким источникам без риска утечки конфиденциальных данных (которые защищены аутентификацией).

    Выводы

    • Браузер использует Same-origin policy, чтобы не обрабатывать AJAX ответы от веб-сайтов расположенных на адресах отличных от адреса с которого была загружена веб страница.
    • Same-origin policy не запрещает генерировать запросы к другим сайтам, но запрещает обрабатывать от них ответ.
    • CORS (Cross-Origin Resource Sharing) механизм, который использует дополнительные заголовки HTTP, чтобы дать браузерам указание предоставить веб-приложению, работающему в одном источнике, доступ к ответу на запрос к ресурсам из другого источника.
    • CORS вместе с credentials (с данными аутентификации) требует осторожности.
    • CORS это браузерная политика. Другие приложения не затрагиваются этим понятием.
    Ссылка на основную публикацию
    Adblock
    detector