CORS кто должен что отправлять? - PullRequest
0 голосов
/ 16 февраля 2020

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

У меня есть следующие компоненты

  1. Браузер: локальный, отображает веб-сайт

  2. Веб-сервер: удаленный, apache, обслуживает http-сайт по порту 80

  3. REST-сервер: удаленный, настраиваемая реализация в golang обслуживает ресурсы на порту 8080 и предлагает три типа ресурсов:

    / api / login (POST)
    / api / foo (GET)
    / api / bar / 0 / sub / 1 (GET и POST)

Все работало нормально, пока вся установка CORS работала только с localhost. Но теперь, когда я пытаюсь выполнить на сервере удаления, я получаю нарушения CORS.

В большей части онлайн-документации обсуждается, что должен делать браузер и сервер, но какой из серверов (веб-сайт и остальные) должен делать то, что ?

Вопрос : кто должен устанавливать, какие Access-Control-Allow-Origin-Headers отправлять запрос на вход?

1 Ответ

1 голос
/ 17 февраля 2020

Следующие заметки, собранные из разных источников, помогли мне как новичку в CORS (которым я все еще определенно являюсь) - так что, возможно, они также помогут другим.

Кроме того, я уверен, что следующие заметки далеко из полной истории. И, как сказал @amon, обратное проксирование - это также способ решения (то есть обхода) CORS.

1) Эта блок-схема CORS

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

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

enter image description here

Три примера, где предварительная проверка необходимы:

  • запрос включает токен аутентификации
  • пользовательские заголовки включены в запрос
  • запрос является ajax вызовом, содержащим JSON или XML полезная нагрузка.

Напротив, запросы, содержащие простые GET s, предварительно не выдвигаются.

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

На сервере, как правило, это фильтр CORS, который контролирует содержимое ответа от сервера обратно в браузер (пример приведен ниже).

Это может быть все, что вам нужно, чтобы получить достаточно полный ответ на вопрос «кто что посылает». Но я все еще был в замешательстве.

Я посмотрел на пример, который помог мне намного больше - см. Ниже.


Я думаю, что лучшее понимание, которое у меня было, по пути было связано с тем, что моему клиентскому приложению не нужно было ничего указывать c для устранения ограничений CORS. Это был браузер, в котором работало мое приложение, которое позаботилось о обработке CORS на стороне клиента. Как говорит @amon, CORS предназначен не для защиты ресурсов, а для того, чтобы помочь браузерам защитить пользователей от вредоносных веб-сайтов .


2) Пример

Просмотр конкретного примера c помог мне понять, кто что отправляет.

Сценарий: в браузере запущено клиентское приложение на https://domainA.com. Он отправляет запрос API на несвязанный сервер (http://anotherdomainX.net).

Пример сервера, который я показываю здесь, - это Tomcat - другие серверы могут иметь существенно разные способы настройки фильтра CORS (я не знаю). Но пример Tomcat довольно подробно раскрывает многие детали.

См. этот вопрос о ServerFault для примера.

Это XML из этого примера:

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>
            http://domainA.com,
            https://domainA.com,
            http://localhost:4200
        </param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>
            Content-Type,
            X-Requested-With,
            Accept,
            Accept-Encoding,
            Accept-Language,
            Origin,
            Access-Control-Request-Method,
            Access-Control-Request-Headers,
            Connection,
            Host,
            authorization
        </param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>
            Access-Control-Allow-Origin,
            Access-Control-Allow-Credentials
        </param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

(Для Tomcat это добавляется в файл конфигурации web.xml в CATALINA_HOME/conf.)

Различные разделы в приведенном выше фильтре задокументированы здесь (Tomcat 9).

Но ключевой момент заключается в том, что именно указанное выше определение фильтра контролирует, какие конкретные c CORS-связанные возвращается с сервера.

В разделе cors.allowed.origins определен белый список. По умолчанию список пуст, что означает, что запросы не проходят, за исключением запросов из того же домена (источника), что и сервер - http://anotherdomainX.net.

3) Имена происхождения

Это в основном что вы видите в адресной строке вашего клиентского веб-приложения. Он должен включать протокол, имя домена и номер порта (если используется). root контекста приложения является , а не частью имени источника.

Так, для URL, такого как https://domainA.com/myapp/getdata, https://domainA.com является именем источника.

4) Почтальон

Это появляется довольно часто. Почему мой вызов API работает в Postman, а не из моего веб-клиента?

Основной ответ c заключается в том, что Postman - это инструмент разработки, а не браузер .

Насколько я понимаю, он использует расширения браузера, которые имеют разные правила, касающиеся обработки XMLHttpRequest.

Такие инструменты, как cURL, также не относятся к CORS, потому что, как говорит @amon CORS предназначен не для защиты ресурсов, а для того, чтобы браузеры могли защитить пользователей от вредоносных веб-сайтов. .

5) null. Origins

. создайте простую веб-страницу в текстовом файле, откройте ее в браузере и получите URL-адрес, подобный следующему:

file:///C:/temp/test.htm

Здесь используется протокол file:. См. здесь для заметок и предупреждений об этом.

6) Publi c API

Вероятно, плохая форма ответа на вопрос, чтобы содержать вопрос, но ...

Как общедоступные службы обрабатывают CORS? Они просто включают "всех" в их cors-allowed-origins?

<init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value> * </param-value>
</init-param>

Я думаю, ответ да . В разделе « общие ошибки » связанная статья гласит:

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


Я был бы рад отредактировать вышеуказанные примечания, чтобы исправить любые ошибки, если это ассигновать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...