В процессе интеграции 1С с современными веб-сервисами программисты часто сталкиваются с необходимостью авторизации через Bearer-токены. На первый взгляд задача кажется простой, особенно если запрос успешно проходит в сторонних программах типа Postman. Однако при переносе логики в код 1С часто возникают ошибки, такие как 400 Bad Request или 401 Unauthorized. В данной статье мы подробно разберем, как правильно настроить HTTPСоединение, сформировать заголовки и избежать типовых ошибок при работе с защищенными протоколами.
Рассмотрим ситуацию: у нас есть статический токен и API сайта, который требует curl-авторизацию. Начальный код, который часто приводит к ошибке 400, обычно выглядит так: создается HTTPСоединение без явного указания защищенного протокола, а токен передается в заголовки в "чистом" виде, без обязательного префикса. Проанализируем, почему это не работает и какие шаги нужно предпринять для исправления.
Современные API практически всегда работают по протоколу HTTPS (порт 443). Если в конструкторе HTTPСоединение не указать объект ЗащищенноеСоединениеOpenSSL, 1С попытается отправить обычный HTTP-запрос на защищенный порт. Сервер либо сбросит соединение, либо вернет ошибку.
Для решения этой задачи мы должны инициализировать объект защищенного соединения. В самом простом случае это выглядит так:
// Инициализируем защищенное соединение
SSL = Новый ЗащищенноеСоединениеOpenSSL();
// Создаем соединение с сервером
Соединение = Новый HTTPСоединение(
"api.site.com", // Хост
443, // Порт
, // Логин (для Bearer оставляем пустым)
, // Пароль (для Bearer оставляем пустым)
, // Прокси
60, // Таймаут
SSL // Защищенное соединение
);
Важное замечание: Если ваш сервер использует самоподписанные сертификаты, стандартный конструктор Новый ЗащищенноеСоединениеOpenSSL() может выдать ошибку проверки. В таких случаях в параметры конструктора необходимо передавать специализированные объекты сертификатов, однако для большинства публичных API стандартного варианта достаточно.
Одной из самых распространенных ошибок является передача самого токена без ключевого слова Bearer. Согласно стандарту RFC 6750, заголовок должен содержать тип токена и пробел перед самим значением ключа.
Разберем, как правильно наполнить Соответствие для заголовков запроса:
ЗаголовокЗапросаHTTP = Новый Соответствие;
// Указываем тип контента, который мы отправляем/ожидаем
ЗаголовокЗапросаHTTP.Вставить("Content-Type", "application/json");
// Добавляем обязательный префикс Bearer к вашему токену
ЗаголовокЗапросаHTTP.Вставить("Authorization", "Bearer " + Токен);
Если пропустить слово Bearer, сервер не поймет способ авторизации и вернет 401 Unauthorized, даже если сам ключ указан верно.
Часто путаница возникает между методами GET и POST. Если ваша задача — получить продажи или остатки (как в примере автора темы), скорее всего, используется метод GET. В 1С это реализуется методом Получить() объекта HTTPСоединение. Если же вы отправляете данные на сайт, используется ОтправитьДляОбработки() (аналог POST).
Рассмотрим пример формирования запроса на получение данных:
// Формируем запрос, указывая ресурс (путь) и заголовки
ПутьКРесурсу = "/api/v1/sales";
Запрос = Новый HTTPЗапрос(ПутьКРесурсу, ЗаголовокЗапросаHTTP);
// Выполняем GET-запрос
HTTPОтвет = Соединение.Получить(Запрос);
// Проверяем результат
Если HTTPОтвет.КодСостояния = 200 Тогда
ТелоОтвета = HTTPОтвет.ПолучитьТелоКакСтроку();
// Далее парсим JSON
Иначе
Сообщить("Ошибка запроса: " + HTTPОтвет.КодСостояния);
КонецЕсли;
Объединим все вышесказанное в единую рабочую процедуру, которую можно использовать в своих обработках:
Функция ПолучитьДанныеССайта(Токен, Сервер, Ресурс) Экспорт
// 1. Настройка SSL
SSL = Новый ЗащищенноеСоединениеOpenSSL();
// 2. Создание соединения. Логин и пароль не заполняем, так как используем токен
Соединение = Новый HTTPСоединение(Сервер, 443, , , , 30, SSL);
// 3. Подготовка заголовков
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Заголовки.Вставить("Content-Type", "application/json");
Заголовки.Вставить("Accept", "application/json"); // Рекомендуется добавить
// 4. Формирование запроса
Запрос = Новый HTTPЗапрос(Ресурс, Заголовки);
Попытка
// 5. Отправка запроса (GET)
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
Возврат Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
Иначе
ЗаписьЖурналаРегистрации("Обмен.Ошибка", УровеньЖурналаРегистрации.Ошибка, , ,
"Код ответа: " + Ответ.КодСостояния + ". Тело: " + Ответ.ПолучитьТелоКакСтроку());
Возврат Неопределено;
EndIf;
Исключение
Сообщить("Ошибка связи: " + ОписаниеОшибки());
Возврат Неопределено;
КонецПопытки;
КонецФункции
Проанализируем ситуации, которые могут возникнуть при промышленной эксплуатации данного кода:
ПолучитьТелоКакСтроку(), 1С обычно корректно определяет кодировку, но для надежности лучше указывать её явно: ПолучитьТелоКакСтроку(КодировкаТекста.UTF8).Заголовки.Вставить("Accept", "application/json");. Это поможет избежать получения HTML-страниц с ошибками вместо структурированных данных.HTTPСоединение должны оставаться пустыми. В некоторых случаях заполнение этих полей приводит к тому, что 1С пытается добавить заголовок Basic-авторизации, что вызывает конфликт на стороне веб-сервера (ошибка 400 или 401).?dateFrom=2023-01-01), обязательно используйте функцию КодироватьСтроку() для параметров, которые могут содержать спецсимволы или кириллицу.User-Agent. Если вы получаете ошибку 403, попробуйте добавить: Заголовки.Вставить("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) 1C-Integration");.Соблюдение этих правил и использование приведенного выше шаблона кода позволит вам быстро и надежно настроить обмен данными с любым сайтом, использующим современную авторизацию по токену.