Как решить проблему с ошибкой 401 Unauthorized при вызове HTTP-сервисов 1С через AJAX?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции сторонних веб-приложений с базами данных 1С программисты часто сталкиваются с неприятной ситуацией. Настроенный HTTP-сервис в 1С прекрасно реагирует на запросы через специализированные утилиты тестирования, например, Postman, возвращая корректный JSON-пакет. Однако при попытке отправить точно такой же запрос из браузера с помощью JavaScript-кода (например, через $.ajax в jQuery) веб-сервер неожиданно возвращает ошибку status of 401 (Unauthorized).

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

Выясняем причину: почему в Postman работает, а в браузере нет?

Для начала давайте разберем механизм работы веб-запросов. Когда мы отправляем запрос через 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. Настройка перехвата запросов OPTIONS на IIS (Рекомендуемый)

Если ваша публикация 1С работает под управлением веб-сервера Microsoft IIS, наилучшим решением будет принудительный перехват всех запросов, приходящих методом OPTIONS, и возвращение для них успешного ответа со статусом 200 OK еще до того, как они дойдут до модуля авторизации 1С.

Для реализации этого сценария нам потребуется официальный модуль расширения для IIS — URL Rewrite (его можно бесплатно скачать с сайта Microsoft и установить на сервер). После установки выполните следующие шаги по шагам:

  1. Перейдите в каталог публикации вашей базы данных 1С на сервере (там, где расположен файл публикации default.vrd).
  2. Найдите или создайте в этой папке файл конфигурации web.config.
  3. Откройте его в текстовом редакторе и приведите структуру секции <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С.

Способ 2. Использование официального модуля Microsoft IIS CORS Module

Если вы используете современные версии операционных систем 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.

Способ 3. Обработка метода OPTIONS непосредственно в коде 1С

Этот метод подходит в тех случаях, когда в файле публикации default.vrd у вас жестко прописан системный пользователь 1С для авторизации (то есть на самом веб-сервере авторизация отключена, и все клиенты заходят в базу под одним скрытым служебным аккаунтом).

Если веб-сервер не требует базовой авторизации на уровне HTTP-подключения, то пустой запрос OPTIONS успешно дойдет до самой платформы 1С. В этом случае мы можем обработать его программно.

  1. Откройте конфигуратор вашей базы данных 1С и перейдите к нужному HTTP-сервису.
  2. Внутри шаблона URL добавьте новый метод с именем OPTIONS.
  3. Создайте для него функцию-обработчик в модуле HTTP-сервиса.
  4. Напишите в обработчике код, возвращающий пустой ответ с заголовками CORS:

Функция ИмяШаблона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С.

Способ 4. Использование реверс-прокси на Nginx

Если инфраструктура публикации ваших сервисов 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 запросы.

Способ 5. Решение для веб-сервера Apache

Если в качестве веб-сервера для публикации баз 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]

Как проверить работоспособность решения?

После внесения изменений в конфигурацию веб-сервера обязательно выполните следующие действия:

  1. Перезапустите ваш веб-сервер (IIS, Apache или службу Nginx) для применения настроек.
  2. Очистите кэш браузера перед повторным тестированием, так как браузеры любят кэшировать неудачные CORS-ответы.
  3. Откройте консоль разработчика в браузере (клавиша F12), перейдите на вкладку Network (Сеть) и выполните ваш AJAX-запрос.
  4. В списке запросов вы должны увидеть два последовательных обращения к вашему адресу HTTP-сервиса: первый с методом OPTIONS (который должен завершиться со статусом 200 OK), и второй — непосредственно ваш POST или GET запрос с кодом 200 OK и возвращаемыми данными в формате JSON.

Используя один из предложенных методов настройки инфраструктуры веб-сервера, вы сможете навсегда решить проблему кроссдоменных ограничений и обеспечить стабильное взаимодействие внешних JS-фреймворков и веб-страниц с HTTP-сервисами на платформе 1С.

← На главную