Интеграция со сторонними сервисами через REST API — повседневная задача для разработчика 1С. Однако переход от простых методов авторизации к использованию токенов (Bearer Token) и особенности работы объекта HTTPСоединение часто вызывают вопросы. В этой статье мы подробно разберем, как правильно передать токен авторизации, почему возникает ошибка разрешения имени хоста и куда пропадает тело запроса при отправке.
Рассмотрим ситуацию, с которой часто сталкиваются разработчики. Изначально обмен данными работал без сложной авторизации: отправлялся XML-файл через POST-запрос. В какой-то момент владелец API меняет правила безопасности и требует передавать токен авторизации в каждом запросе.
Обычно документация к API гласит: "Токен необходимо передавать в заголовке Authorization". Давайте разберем по шагам, как это реализовать на встроенном языке 1С и какие подводные камни нас ожидают.
Стандартным способом передачи токена (например, при реализации Google OAuth 2.0 на обычных формах) является использование HTTP-заголовка Authorization со схемой Bearer. Это означает, что к самому токену нужно добавить префикс "Bearer " (с пробелом на конце).
В 1С для работы с заголовками используется объект Соответствие. Давайте посмотрим, как правильно добавить этот заголовок:
Токен = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."; // Ваш длинный токен
Заголовки = Новый Соответствие();
// Обязательно добавляем пробел после слова Bearer
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Затем это соответствие передается в конструктор HTTPЗапрос или в метод отправки, если используется упрощенный вызов.
Одной из самых распространенных ошибок при настройке HTTPСоединение является неправильное указание адреса сервера. Рассмотрим пример кода, который приведет к ошибке:
// ОШИБКА: Так делать нельзя
Сервер = "https://riester-lk.grphn-dev.ru/json/order/bill/";
HTTP = Новый HTTPСоединение(Сервер, , , , , , ssl1);
При выполнении этого кода платформа вернет ошибку: Couldn't resolve host name.
Почему это происходит?
Конструктор HTTPСоединение в первом параметре ожидает получить только имя хоста (домен или IP-адрес). Он не умеет "выкусывать" домен из полной строки URL. Он пытается найти в DNS запись для имени https://riester-lk.grphn-dev.ru/json/order/bill/, что, естественно, невозможно.
Как сделать правильно?
Необходимо разделить полный адрес на три составляющие:
ЗащищенноеСоединениеOpenSSL.HTTPСоединение.HTTPЗапрос.Исправим наш код:
// 1. Указываем только домен
Сервер = "riester-lk.grphn-dev.ru";
// 2. Настраиваем SSL (для https)
ssl = Новый ЗащищенноеСоединениеOpenSSL(
Новый СертификатКлиентаWindows(),
Новый СертификатыУдостоверяющихЦентровWindows());
// 3. Создаем соединение
HTTP = Новый HTTPСоединение(Сервер, , , , , , ssl);
// 4. Путь к конкретному методу API указываем здесь
АдресРесурса = "/json/order/bill/";
ЗапросHTTP = Новый HTTPЗапрос(АдресРесурса, Заголовки);
Часто бывает ситуация, когда соединение установлено, заголовки (включая токен) уходят верно, сервер отвечает кодом 200, но при этом сообщает, что необходимые данные не получены. Это означает, что тело запроса (body) не дошло до сервера или сформировано некорректно.
Проанализируем ошибку в логике кода, который часто пишут новички, пытаясь отправить данные:
// Пример ОШИБОЧНОГО кода
ТелоPOSTЗапроса = "token: ... order-id: ...";
ЗапросHTTP.УстановитьТелоИзСтроки(ТелоPOSTЗапроса, КодировкаТекста.ANSI);
// Внимание на следующую строку!
ЗапросHTTP.УстановитьИмяФайлаТела(ИмяФайлаОтправки);
ОтветHTTP = HTTP.ОтправитьДляОбработки(ЗапросHTTP, ФайлРезультата);
В чем проблема?
Методы УстановитьТелоИзСтроки и УстановитьИмяФайлаТела являются взаимоисключающими для одного объекта запроса. Если вы сначала установили тело из строки, а затем вызвали установку из файла (даже если переменная с именем файла пуста), платформа 1С будет пытаться отправить файл. Строка, которую вы формировали ранее, будет проигнорирована и перезаписана.
В результате на сервер уходит пустой запрос (или содержимое случайного файла), хотя вы ожидаете отправку сформированной строки.
Также важно отметить, что ручное формирование тела запроса для формата multipart/form-data — это плохая практика. Судя по адресу ресурса в примере (/json/...), сервер вероятнее всего ожидает данные в формате JSON. Чтобы гарантировать корректность структуры, может потребоваться предварительная проверка на заполненность обязательных полей в строке JSON.
Правильный алгоритм действий:
Content-Type.Content-Length (платформа сделает это сама).Пример корректного кода (такой подход часто используется, когда реализуется интеграция 1С с Google Таблицами через сервисный аккаунт):
// 1. Подготовка данных
СтруктураДанных = Новый Структура;
СтруктураДанных.Вставить("token", "IUH36POKWED87...");
СтруктураДанных.Вставить("order-id", "147");
// 2. Сериализация в JSON
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, СтруктураДанных);
СтрокаJSON = ЗаписьJSON.Закрыть();
// 3. Настройка заголовков
Заголовки = Новый Соответствие();
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
// 4. Инициализация запроса
Сервер = "riester-lk.grphn-dev.ru";
АдресРесурса = "/json/order/bill/";
ЗапросHTTP = Новый HTTPЗапрос(АдресРесурса, Заголовки);
// 5. Установка тела (ТОЛЬКО ОДИН МЕТОД)
ЗапросHTTP.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8);
// 6. Отправка
ssl = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows(), Новый СертификатыУдостоверяющихЦентровWindows());
HTTP = Новый HTTPСоединение(Сервер, , , , , , ssl);
Ответ = HTTP.ОтправитьДляОбработки(ЗапросHTTP);
В некоторых случаях, например, когда требуется получение токена авторизации RuStore с подписью RSA, процедура формирования тела и заголовков может включать дополнительные криптографические операции.
Если вы все сделали правильно, но сервер все равно возвращает ошибку, рекомендуем использовать следующие приемы (поможет обработка для пошаговой отладки кода в режиме Предприятие):
ЗапросHTTP.ПолучитьТелоКакСтроку() в отладчике — для этого пригодится набор инструментов для ускорения разработки и отладки на 1С.HTTPСоединение на работу через прокси (например, Fiddler), чтобы увидеть реальное форматирование тела.Соблюдение этих правил позволит вам избежать большинства типовых проблем при интеграции 1С с веб-сервисами.