Проблемы CORS всегда лучше.
Что такое CORS?
Ваш браузер пытается защитить пользователей от перенаправления на страницу, которую они считают интерфейсом для API, но на самом деле это мошенничество. Каждый раз, когда веб-страница пытается получить доступ к API в другом домене, этот API должен явно предоставить разрешение веб-странице, иначе браузер заблокирует запрос. Вот почему вы можете запрашивать API из Node.js (без браузера) и помещать адрес REST API прямо в адресную строку (в том же домене). Однако попытка перейти с localhost:3000
на localhost:8008
или с file://path/to/your/index.html
на localhost:8008
будет заблокирована.
Почему Sawtooth REST API не обрабатывает запросы OPTIONS?
API-интерфейс Sawtooth REST не знает, из какого домена вы собираетесь запускать веб-страницу, поэтому не может явно занести его в белый список. Можно внести в белый список все домены, но это, очевидно, разрушит любую защиту, которую CORS может вам предоставить. Вместо того, чтобы пытаться взвесить затраты и преимущества этого подхода для всех пользователей Sawtooth повсюду, было принято решение сделать REST API как можно более легким и независимым от безопасности. Ожидается, что любой разработчик, использующий его, разместит его за прокси-сервером, и он сможет принимать любые необходимые решения по безопасности на этом прокси-уровне.
Так как же это исправить?
Вам необходимо настроить прокси-сервер, который разместит REST API и вашу веб-страницу в одном домене. Для этого нет возможности быстрой настройки. Вам нужно будет настроить реальный сервер. Очевидно, есть много способов сделать это. Если вы уже знакомы с Node, вы можете обслуживать страницу из Node.js, а затем использовать прокси-сервер Node, который вызывает API. Если вы уже запускаете все компоненты Sawtooth с docker-compose
, возможно, будет проще использовать Docker и Apache.
Настройка прокси-сервера Apache с помощью Docker
Создайте свой Dockerfile
В том же каталоге, что и ваше веб-приложение, создайте текстовый файл с именем «Dockerfile» (без расширения). Тогда сделайте так:
FROM httpd:2.4
RUN echo "\
LoadModule proxy_module modules/mod_proxy.so\n\
LoadModule proxy_http_module modules/mod_proxy_http.so\n\
ProxyPass /api http://rest-api:8008\n\
ProxyPassReverse /api http://rest-api:8008\n\
RequestHeader set X-Forwarded-Path \"/api\"\n\
" >>/usr/local/apache2/conf/httpd.conf
Это сделает пару вещей. Сначала он извлечет модуль httpd
из DockerHub, который представляет собой простой статический сервер. Затем мы используем немного bash, чтобы добавить пять строк в файл конфигурации Apache. Эти пять строк импортируют прокси-модули, сообщают Apache, что мы хотим прокси http://rest-api:8008
на /api
маршрут, и устанавливаем заголовок X-Forwarded-Path
, чтобы REST API мог правильно создавать URL-адреса ответов. Убедитесь, что rest-api
соответствует фактическому имени службы Sawtooth REST API в вашем файле компоновки докеров.
Измените файл создания докеров
Теперь, когда докер создаст файл YAML, через который вы запускаете Sawtooth, вы хотите добавить новое свойство под ключом services
:
services:
my-web-page:
build: ./path/to/web/dir/
image: my-web-page
container_name: my-web-page
volumes:
- ./path/to/web/dir/public/:/usr/local/apache2/htdocs/
expose:
- 80
ports:
- '8000:80'
depends_on:
- rest-api
Это создаст ваш Dockerfile, расположенный в ./path/to/web/dir/Dockerfile
(относительно файла компоновки докеров), и запустит его с командой по умолчанию, которая предназначена для запуска Apache. Apache будет обслуживать все файлы, расположенные в /usr/local/apache2/htdocs/
, поэтому мы будем использовать volumes
, чтобы связать путь к вашим веб-файлам на вашем хост-компьютере (т.е. ./path/to/web/dir/public/
) с этим каталогом в контейнере. По сути, это псевдоним, поэтому, если вы обновите свое веб-приложение позже, вам не нужно перезапускать этот контейнер докеров, чтобы увидеть изменения. Наконец, ports
возьмет сервер, который находится в порту 80
внутри контейнера, и перенаправит его на localhost:8000
.
Запуск всего этого
Теперь вы можете запустить:
docker-compose -f path/to/your/compose-file.yaml up
И он запустит ваш сервер Apache вместе с Sawtooth REST API, валидатором и любыми другими службами, которые вы определили. Если вы перейдете на http://localhost:8000
, вы должны увидеть свою веб-страницу, а если вы перейдете на http://localhost:8000/api/blocks
, вы должны увидеть JSON-представление блоков в цепочке. Что еще более важно, вы должны иметь возможность отправлять запросы из своего веб-приложения:
request.post({
url: 'api/batches',
body: batchListBytes,
headers: { 'Content-Type': 'application/octet-stream' }
}, (err, response) => console.log(response) );
Уф. Извините за длинный ответ, но я не уверен, можно ли решить CORS быстрее. Надеюсь, это поможет.
person
Zac Delventhal
schedule
15.03.2018