При интеграции сторонних веб-приложений с базами данных 1С программисты часто сталкиваются с неприятной ситуацией. Настроенный HTTP-сервис в 1С прекрасно реагирует на запросы через специализированные утилиты тестирования, например, Postman, возвращая корректный JSON-пакет. Однако при попытке отправить точно такой же запрос из браузера с помощью JavaScript-кода (например, через $.ajax в jQuery) веб-сервер неожиданно возвращает ошибку status of 401 (Unauthorized).
В этой статье мы подробно проанализируем ситуацию, выясним глубинную причину такого поведения браузеров и разберем несколько практических способов решения этой проблемы для различных конфигураций веб-серверов.
Для начала давайте разберем механизм работы веб-запросов. Когда мы отправляем запрос через Postman, этот инструмент работает как классический клиент (подобно операционной системе или десктопному приложению). Он отправляет запрос напрямую на веб-сервер 1С, прикрепляя к нему заголовки авторизации, такие как Authorization: Basic .... Веб-сервер успешно проверяет учетные данные и возвращает результат.
В браузере ситуация принципиально иная. Здесь вступают в силу строгие правила безопасности, а именно механизм CORS (Cross-Origin Resource Sharing) — совместное использование ресурсов между разными источниками. Если скрипт, инициирующий AJAX-запрос, выполняется на одном домене (например, my-site.ru), а HTTP-сервис 1С опубликован на другом (например, 10.1.1.9 или другой IP/домен), браузер классифицирует этот запрос как кроссдоменный.
Для защиты целевого сервера браузер перед отправкой фактического запроса (в нашем случае POST) выполняет предварительный проверочный запрос — так называемый Preflight request методом OPTIONS. Браузер как бы спрашивает у сервера 1С: «Разрешено ли сайту my-site.ru отправлять тебе POST-запросы с заголовком авторизации?».
Главная проблема кроссдоменного механизма: согласно спецификации консорциума W3C, браузер отправляет проверочный запрос OPTIONS без заголовка авторизации Authorization. Поскольку публикация 1С на веб-сервере (IIS или Apache) защищена авторизацией, веб-сервер получает «пустой» запрос OPTIONS, не находит в нем логина и пароля и мгновенно отклоняет его с ошибкой 401 Unauthorized. До реального отправления вашего POST-запроса дело даже не доходит.
Обычное добавление заголовка Access-Control-Allow-Origin в файл конфигурации web.config без дополнительной настройки не решает проблему, так как модуль авторизации веб-сервера срабатывает раньше, чем обрабатываются эти заголовки. Ниже мы детально разберем рабочие способы обхода этой проблемы.
Если ваша публикация 1С работает под управлением веб-сервера Microsoft IIS, наилучшим решением будет принудительный перехват всех запросов, приходящих методом OPTIONS, и возвращение для них успешного ответа со статусом 200 OK еще до того, как они дойдут до модуля авторизации 1С.
Для реализации этого сценария нам потребуется официальный модуль расширения для IIS — URL Rewrite (его можно бесплатно скачать с сайта Microsoft и установить на сервер). После установки выполните следующие шаги по шагам:
default.vrd).web.config.<system.webServer> к следующему виду:
<configuration>
<system.webServer>
<!-- Шаг 1. Конфигурируем заголовки CORS для ответов сервера -->
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
</httpProtocol>
<!-- Шаг 2. Перехватываем preflight-запросы OPTIONS модулем URL Rewrite -->
<rewrite>
<rules>
<rule name="CORS Preflight Anonymous" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{REQUEST_METHOD}" pattern="^OPTIONS$" />
</conditions>
<action type="CustomResponse" statusCode="200" statusReason="OK" statusDescription="Preflight Allowed" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Проанализируем, как работает эта конфигурация. Когда браузер отправляет проверочный запрос OPTIONS, модуль URL Rewrite перехватывает его, видит соответствие шаблону метода и сразу же возвращает браузеру пустой ответ со статусом 200 OK, прикрепив необходимые заголовки CORS. Браузер убеждается, что сервер готов принимать запросы, и следом отправляет настоящий POST-запрос, в котором уже присутствует заголовок Authorization, и этот запрос успешно проходит авторизацию в 1С.
Если вы используете современные версии операционных систем Windows Server и веб-сервер IIS 10, вы можете воспользоваться специализированным расширением — Microsoft IIS CORS Module. Этот модуль спроектирован специально для корректной обработки подобных ситуаций на системном уровне.
После установки модуля на сервер IIS вам достаточно лаконично описать правила поведения для кроссдоменных запросов в файле web.config:
<system.webServer>
<cors enabled="true" failUnlistedOrigins="false">
<add origin="*" allowCredentials="true">
<allowHeaders allowAllRequestedHeaders="true" />
<allowMethods>
<add method="GET" />
<add method="POST" />
<add method="OPTIONS" />
<add method="PUT" />
<add method="DELETE" />
</allowMethods>
</add>
</cors>
</system.webServer>
Этот способ более изящен, так как IIS CORS Module сам управляет жизненным циклом запросов OPTIONS, корректно возвращая ответы на preflight-запросы без необходимости написания сложных правил перезаписи URL.
Этот метод подходит в тех случаях, когда в файле публикации default.vrd у вас жестко прописан системный пользователь 1С для авторизации (то есть на самом веб-сервере авторизация отключена, и все клиенты заходят в базу под одним скрытым служебным аккаунтом).
Если веб-сервер не требует базовой авторизации на уровне HTTP-подключения, то пустой запрос OPTIONS успешно дойдет до самой платформы 1С. В этом случае мы можем обработать его программно.
Функция ИмяШаблонаOPTIONS(Запрос)
Ответ = Новый HTTPСервисОтвет(200); // Возвращаем успешный статус 200 OK
// Пытаемся динамически определить источник запроса
Origin = Запрос.Заголовки.Получить("Origin");
Если Origin = Неопределено Тогда
Origin = "*";
КонецЕсли;
// Заполняем обязательные CORS-заголовки
Ответ.Заголовки.Вставить("Access-Control-Allow-Origin", Origin);
Ответ.Заголовки.Вставить("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, Cache-Control");
Ответ.Заголовки.Вставить("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
Ответ.Заголовки.Вставить("Access-Control-Allow-Credentials", "true");
Возврат Ответ;
КонецФункции
Важное предостережение: если на веб-сервере включена базовая авторизация (Basic Auth) и в файле публикации нет сохраненных учетных данных, этот метод работать не будет. Веб-сервер прервет запрос на этапе проверки авторизации и выдаст 401 ошибку до того, как управление будет передано платформе 1С.
Если инфраструктура публикации ваших сервисов 1С включает в себя прокси-сервер Nginx (который часто устанавливается «перед» IIS или Apache для балансировки нагрузки, кэширования и обеспечения безопасности), вы можете переложить всю логику обработки CORS на него.
В конфигурационном файле Nginx (обычно nginx.conf) в блоке описания виртуального хоста server добавьте перехват метода OPTIONS:
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 200;
}
proxy_pass http://10.1.1.9; # Перенаправляем реальные запросы на IIS с 1С
}
Этот подход освобождает IIS от необходимости сложной настройки модулей перезаписи и гарантирует, что 1С будет получать только очищенные и готовые к авторизации POST и GET запросы.
Если в качестве веб-сервера для публикации баз 1С вы используете Apache, то аналогичный перехват и добавление заголовков можно настроить через файл конфигурации .htaccess (расположенный в папке публикации рядом с файлом default.vrd) или непосредственно в файле httpd.conf.
Для этого убедитесь, что в Apache включены модули mod_headers и mod_rewrite, и добавьте следующие строки конфигурации:
# Включаем принудительную установку заголовков CORS
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control"
Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"
Header always set Access-Control-Allow-Credentials "true"
# Если пришел запрос OPTIONS, перехватываем его и сразу отдаем 200 OK
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
После внесения изменений в конфигурацию веб-сервера обязательно выполните следующие действия:
OPTIONS (который должен завершиться со статусом 200 OK), и второй — непосредственно ваш POST или GET запрос с кодом 200 OK и возвращаемыми данными в формате JSON.Используя один из предложенных методов настройки инфраструктуры веб-сервера, вы сможете навсегда решить проблему кроссдоменных ограничений и обеспечить стабильное взаимодействие внешних JS-фреймворков и веб-страниц с HTTP-сервисами на платформе 1С.