Как подключиться к веб-сервису по HTTPS с использованием токена в 1С и исправить ошибку 307 Redirect

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

При интеграции 1С с современными внешними веб-сервисами (API) разработчики часто сталкиваются с необходимостью авторизации по протоколу HTTPS с использованием токенов безопасности (в частности, Bearer-токенов). На этапе тестирования запросов в специализированных инструментах, таких как Postman, всё работает корректно, однако при переносе логики в код 1С могут возникать непредвиденные трудности. Одной из типичных проблем является внезапный сбой обмена с возвратом HTTP-статуса 307 Temporary Redirect.

В этой статье мы подробно разберем, как правильно реализовать подключение к API с передачей токена в 1С, выясним технические причины возникновения ошибки 307 и рассмотрим надежные способы ее устранения.

Шаг 1. Передача токена авторизации в HTTP-запросе 1С

Большинство современных REST API используют заголовок Authorization с типом авторизации Bearer. Это означает, что для каждого запроса к защищенному ресурсу сервер ожидает получить строковый ключ (токен) в заголовках пакета.

Рассмотрим стандартный шаблон формирования такого запроса в 1С. Для отправки данных мы будем использовать встроенные объекты платформы: HTTPСоединение и HTTPЗапрос.

Давайте проанализируем пример кода, выполняющего отправку POST-запроса с JSON-телом и Bearer-авторизацией:


// Определим параметры подключения и авторизации
АдресСервера = "api.yourservice.com";
РесурсПуть   = "/v1/orders";
ТокенДоступа = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."; // Пример JWT-токена

// Создаем HTTP-соединение. Пока без параметров шифрования.
HTTPСоединение = Новый HTTPСоединение(АдресСервера);

// Подготавливаем HTTP-запрос
HTTPЗапрос = Новый HTTPЗапрос();
HTTPЗапрос.АдресРесурса = РесурсПуть;

// Добавляем обязательные заголовки
HTTPЗапрос.Заголовки.Вставить("Authorization", "Bearer " + ТокенДоступа);
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

// Формируем тело запроса (в данном случае отправляем файл JSON)
ИмяФайлаОтправки = ПолучитьИмяВременногоФайла("json");
// Код заполнения файла JSON...
HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаОтправки);

// Инициируем отправку запроса
ИмяФайлаОтвета = ПолучитьИмяВременногоФайла("json");
Попытка
    HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос, ИмяФайлаОтвета);
    // Обработка успешного ответа сервера
Исключение
    ЗаписатьЛогОшибки(ИнформацияОбОшибке().Описание);
КонецПопытки;

В данном примере ключевым моментом является строка добавления заголовка Authorization. Обратите внимание на обязательное наличие пробела после слова Bearer перед склейкой со строкой токена.

Шаг 2. Разбор проблемы: Ошибка HTTP 307 (Temporary Redirect)

Представим ситуацию: ваш интеграционный код успешно работал на протяжении нескольких недель, но в один момент перестал функционировать, а сервер начал возвращать код состояния 307. Что это означает и почему происходит сбой?

Код состояния 307 Temporary Redirect (Временное перенаправление) указывает на то, что запрашиваемый ресурс временно перенесен на другой адрес (URI), указанный в заголовке ответа Location. Главная особенность этого статуса заключается в том, что клиент при повторном запросе к новому адресу **не имеет права изменять метод запроса** (например, заменять POST на GET). Тело исходного запроса должно быть отправлено повторно.

В контексте веб-сервисов 1С наиболее частая причина возникновения редиректа 307 — это **принудительное перенаправление со стандартного протокола HTTP на защищенный HTTPS**. Веб-сервис, к которому вы обращаетесь, перешел на обязательное использование SSL/TLS-шифрования.

Если в коде 1С объект HTTPСоединение инициализирован без явного указания защищенного соединения, платформа пытается отправить запрос по незащищенному порту 80 (HTTP). Веб-сервер перехватывает его и возвращает статус 307 вместе с новым защищенным адресом (начинающимся с https://). Сама платформа 1С по соображениям безопасности не производит автоматический редирект для запросов, содержащих тело данных (POST/PUT), в результате чего выполнение интеграции прерывается с ошибкой.

Шаг 3. Решение проблемы с помощью защищенного SSL-соединения

Для того чтобы избежать промежуточных ренаправлений (редиректов) и сразу адресовать запрос на защищенный порт сервера (443), необходимо явно объявить использование защищенного соединения при инициализации объекта HTTPСоединение.

Для реализации защищенного соединения в платформе 1С предусмотрен специализированный объект ЗащищенноеСоединениеOpenSSL. Давайте посмотрим, как изменится наш код инициализации соединения:


// Создаем объект защищенного соединения OpenSSL. 
// По умолчанию используются системные сертификаты операционной системы.
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();

// Инициализируем соединение с явным указанием защищенного протокола
// Порт 443 подставится автоматически, так как передано защищенное соединение
HTTPСоединение = Новый HTTPСоединение(
    АдресСервера,             // Сервер
    ,                         // Порт (не указываем, определится автоматически)
    ,                         // Пользователь
    ,                         // Пароль
    ,                         // Прокси
    ,                         // Таймаут
    ЗащищенноеСоединение      // Защищенное соединение OpenSSL
);

Добавление всего одной строки с объявлением ЗащищенноеСоединениеOpenSSL заставляет 1С отправлять шифрованные запросы по протоколу HTTPS. Сервер мгновенно принимает запрос без возврата статуса 307 Redirect, и логика обмена восстанавливается.

Шаг 4. Особенности работы SSL в операционных системах Windows и Linux

Простое создание объекта ЗащищенноеСоединениеOpenSSL() без передачи параметров отлично функционирует на серверах и рабочих станциях под управлением Windows. Это связано с тем, что платформа 1С обращается к встроенному хранилищу сертификатов Windows для подтверждения доверия к центру сертификации (CA) веб-сервиса.

Однако, если ваш сервер приложений 1С развернут на операционной системе **Linux**, могут возникнуть сложности. Серверная платформа 1С на Linux не имеет прямого доступа к централизованному системному хранилищу сертификатов. Вместо этого используется локальный файл-хранилище доверенных сертификатов — cacert.pem, поставляемый вместе с платформой (находится в директории установленной платформы, например: /opt/1cv8/x86_64/[версия_платформы]/bin/cacert.pem).

Если сертификат вашего API выпущен современным или локальным некоммерческим удостоверяющим центром (например, Let's Encrypt или Минцифры РФ), которого нет в стандартной поставке файла cacert.pem, 1С выдаст ошибку рукопожатия SSL (Handshake Error). Для исправления этой ситуации выполните следующие действия:

  1. Скачайте корневые и промежуточные сертификаты веб-сервиса в формате Base64 (расширение .crt или .pem).
  2. Откройте скачанные файлы текстовым редактором и скопируйте их содержимое (блоки, начинающиеся с -----BEGIN CERTIFICATE----- и заканчивающиеся на -----END CERTIFICATE-----).
  3. Откройте файл cacert.pem на сервере 1С под управлением Linux.
  4. Добавьте скопированное текстовое содержимое сертификатов в самый конец файла cacert.pem и сохраните изменения.

Шаг 5. Универсальный шаблон защищенного запроса с обработкой ошибок

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


Функция ВыполнитьЗапросКСервису(АдресСервера, ПутьКРесурсу, ТокенАвторизации, ДанныеЗапросаJSON) Экспорт

    РезультатВыполнения = Новый Структура("Успех, КодСостояния, Ответ");
    РезультатВыполнения.Успех = Ложь;
    
    // Создаем объект SSL-защиты
    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
    
    // Инициализируем защищенное HTTPS-соединение
    Попытка
        HTTPСоединение = Новый HTTPСоединение(
            АдресСервера,
            443, // Явно указываем стандартный порт HTTPS
            , , , 30, // Таймаут 30 секунд
            ЗащищенноеСоединение
        );
    Исключение
        РезультатВыполнения.Ответ = "Не удалось установить соединение с сервером: " + ОписаниеОшибки();
        Возврат РезультатВыполнения;
    КонецПопытки;
    
    // Формируем запрос
    HTTPЗапрос = Новый HTTPЗапрос(ПутьКРесурсу);
    HTTPЗапрос.Заголовки.Вставить("Authorization", "Bearer " + ТокенАвторизации);
    HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
    HTTPЗапрос.УстановитьТелоИзСтроки(ДанныеЗапросаJSON, КодировкаТекста.UTF8, ИспользованиеМаркераПоследовательностиБайтов.НеИспользовать);
    
    // Отправляем запрос и получаем ответ сервера
    Попытка
        HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
        
        РезультатВыполнения.КодСостояния = HTTPОтвет.КодСостояния;
        РезультатВыполнения.Ответ = HTTPОтвет.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
        
        Если HTTPОтвет.КодСостояния = 200 Или HTTPОтвет.КодСостояния = 201 Тогда
            РезультатВыполнения.Успех = Истина;
        ИначеЕсли HTTPОтвет.КодСостояния = 307 Тогда
            // Извлекаем адрес перенаправления, если это необходимо обработать программно
            АдресПеренаправления = HTTPОтвет.Заголовки.Получить("Location");
            РезультатВыполнения.Ответ = "Сервер запросил временное перенаправление на адрес: " + АдресПеренаправления;
        Иначе
            РезультатВыполнения.Ответ = "Сервер вернул ошибку: " + HTTPОтвет.КодСостояния + ". Ответ: " + РезультатВыполнения.Ответ;
        КонецЕсли;
        
    Исключение
        РезультатВыполнения.Ответ = "Сбой при передаче данных: " + ОписаниеОшибки();
    КонецПопытки;
    
    Возврат РезультатВыполнения;

КонецФункции

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

← На главную