Как получить токен авторизации в 1С, передавая логин и пароль в теле HTTP-запроса?

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

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

Основной вопрос, который задает автор темы, заключается в том, как преобразовать успешный запрос из Postman в рабочий код 1С, особенно когда учетные данные передаются в теле запроса в формате RAW. Мы выясним, какие объекты 1С нам понадобятся, как правильно сформировать заголовки и тело запроса, и как обработать полученный ответ. Для проверки и отладки запросов непосредственно в 1С пригодится консоль HTTP-запросов для управляемых форм.

Шаг 1: Подготовка HTTP-соединения и объекта запроса

Прежде чем отправить данные на удаленный сервер, нам необходимо инициализировать два ключевых объекта 1С: HTTPСоединение и HTTPЗапрос. Объект HTTPСоединение будет отвечать за установление и поддержание связи с сервером (будь то HTTP или HTTPS), а HTTPЗапрос — за формирование самого запроса, включая его заголовки, метод (POST, GET и т.д.) и, конечно же, тело запроса.

Мы начнем с определения адреса сервера и создания объекта соединения. Если наш целевой сервис использует защищенное соединение (HTTPS), то нам также потребуется объект ЗащищенноеСоединениеOpenSSL.


// Определяем адрес сервера, к которому будем обращаться.
// Например, если URL авторизации - https://api.example.com/api/token,
// то АдресСервера будет "api.example.com".
АдресСервера = "api.example.com"; 

// Если целевой сервис использует HTTPS (обычно порт 443), необходимо
// создать объект защищенного соединения. Это обязательное условие
// для работы с HTTPS-ресурсами.
SSL = Новый ЗащищенноеСоединениеOpenSSL;

// Инициализируем HTTP-соединение.
// Параметры:
// 1. Сервер: доменное имя или IP-адрес сервера.
// 2. Порт: 443 для HTTPS, 80 для HTTP (или иной, если указан).
// 3. Путь к прокси-серверу: если требуется (оставляем пустым, если нет).
// 4. Пользователь прокси: если требуется аутентификация на прокси.
// 5. Пароль прокси: если требуется аутентификация на прокси.
// 6. Таймаут: время ожидания ответа в секундах.
// 7. Защищенное соединение: наш объект SSL для HTTPS.
Соединение = Новый HTTPСоединение(АдресСервера, 443, , , , , SSL);

После создания HTTPСоединения, мы готовы к формированию конкретного HTTPЗапроса. Однако, прежде чем заполнять тело запроса, нам необходимо позаботиться о правильных заголовках.

Шаг 2: Установка заголовков HTTP-запроса

Одним из ключевых моментов, который мы обязательно должны учесть при формировании HTTP-запроса, является правильная установка заголовка Content-Type. Этот заголовок информирует сервер о формате данных, которые мы передаем в теле запроса. Ошибки в его определении могут привести к тому, что сервер не сможет корректно разобрать наши учетные данные, и авторизация не будет выполнена.

Рассмотрим два наиболее распространенных сценария, с которыми мы можем столкнуться при передаче логина и пароля в теле запроса:

  1. Для JSON-данных: Если сервер ожидает данные в формате JSON (что является очень распространенной практикой для современных API), то заголовок должен быть application/json. Часто также рекомендуется указывать кодировку, например: application/json; charset=utf-8.
  2. Для данных формы (application/x-www-form-urlencoded): В некоторых случаях, даже при отправке структурированных данных, сервер может ожидать формат, аналогичный отправке HTML-формы. В этом случае данные в теле запроса должны быть представлены в виде пар "ключ=значение", соединенных амперсандами: ключ1=значение1&ключ2=значение2.

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


// Создаем соответствие для хранения заголовков запроса.
Заголовки = Новый Соответствие;
// Устанавливаем заголовок Content-Type, указывая, что тело запроса будет в формате JSON
// с кодировкой UTF-8. Это критически важно для корректной обработки сервером.
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

// Создаем HTTP-запрос.
// Первый параметр - это относительный путь к ресурсу на сервере.
// Например, если полный URL: https://api.example.com/api/token, то путь будет "/api/token".
// Второй параметр - это соответствие с нашими заголовками.
HTTPЗапрос = Новый HTTPЗапрос("/api/token", Заголовки);

Важно отметить, что метод HTTP-запроса для получения токена авторизации почти всегда будет POST, поскольку мы отправляем данные на сервер. Объект HTTPЗапрос по умолчанию использует метод GET, но при вызове УстановитьТелоИзСтроки() он автоматически переключается на POST, если тело не пустое, или мы можем явно указать метод с помощью HTTPЗапрос.Метод = "POST".

Шаг 3: Формирование тела запроса (логин и пароль)

Теперь мы подходим к самой сути нашей задачи — передаче логина и пароля в теле запроса. Как и было предложено в одном из полезных сообщений на форуме, для установки тела запроса используется метод УстановитьТелоИзСтроки() объекта HTTPЗапрос.

Однако просто передать строку "логин=...", "пароль=..." может быть недостаточно, если сервер ожидает данные в определенном формате (например, JSON). Для формирования тела запроса, особенно когда сервер ожидает JSON, рекомендуется использовать встроенные в 1С механизмы для работы с JSON. Это делает наш код более надежным, исключает синтаксические ошибки и обеспечивает правильное кодирование данных.

Рассмотрим подробнее процесс формирования JSON-строки для тела запроса:

  1. Создаем структуру с данными для авторизации: Сначала мы сформируем обычную структуру 1С, которая будет содержать наши учетные данные. Ключи этой структуры должны соответствовать именам полей, которые ожидает сервер (например, "username" и "password").
  2. Преобразуем структуру в строку JSON: Используя объекты ЗаписьJSON и глобальную функцию ЗаписатьJSON(), мы преобразуем нашу структуру в необходимый JSON-формат. Это гарантирует правильное экранирование символов и соответствие JSON-стандарту.
  3. Устанавливаем тело запроса: Полученную JSON-строку мы передаем в метод УстановитьТелоИзСтроки(). Критически важно обратить внимание на параметр ИспользованиеByteOrderMark.НеИспользовать. Этот параметр предотвращает добавление маркера последовательности байтов (BOM) в начало строки. Некоторые серверы крайне чувствительны к этому маркеру и могут некорректно обрабатывать JSON, содержащий BOM, что приведет к ошибкам авторизации.

Давайте посмотрим на пример кода, который демонстрирует этот процесс:


// Создаем структуру 1С, которая будет содержать наши учетные данные.
// Ключи структуры ("username", "password") должны строго соответствовать
// именам полей, которые ожидает удаленный API для авторизации.
ДанныеАвторизации = Новый Структура;
ДанныеАвторизации.Вставить("username", "testuser");     // Имя пользователя для авторизации
ДанныеАвторизации.Вставить("password", "password123");  // Пароль пользователя

// Инициализируем объект ЗаписьJSON. Он используется для формирования JSON-строки.
ЗаписьJSON = Новый ЗаписьJSON;
// Указываем, что запись JSON будет производиться в строку.
ЗаписьJSON.УстановитьСтроку();

// Преобразуем нашу структуру ДанныеАвторизации в JSON-формат
// и записываем его в ЗаписьJSON.
ЗаписатьJSON(ЗаписьJSON, ДанныеАвторизации);

// Закрываем запись JSON и получаем сформированную строку JSON.
СтрокаJSON = ЗаписьJSON.Закрыть();

// Устанавливаем полученную JSON-строку в качестве тела HTTP-запроса.
// Параметры:
// 1. СтрокаJSON: сформированная строка с данными.
// 2. КодировкаТекста.UTF8: указываем кодировку, в которой будет передана строка.
// 3. ИспользованиеByteOrderMark.НеИспользовать: Очень важный параметр,
//    предотвращающий добавление BOM. Без него сервер может некорректно
//    разобрать JSON.
HTTPЗапрос.УстановитьТелоИзСтроки(СтрокаJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Шаг 4: Отправка запроса и обработка ответа

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

Рассмотрим этот процесс по шагам:

  1. Отправка запроса: Для отправки запроса мы используем метод ОтправитьДляОбработки() объекта HTTPСоединение. Настоятельно рекомендуем обернуть эту операцию в блок Попытка...Исключение. Это позволит нам корректно отлавливать и обрабатывать возможные сетевые ошибки, проблемы с соединением или другие непредвиденные ситуации, которые могут возникнуть в процессе отправки запроса.
  2. Проверка статуса ответа: После получения ответа от сервера мы должны всегда проверять его код состояния. Успешный ответ обычно имеет код 200. Любой другой код (например, 400-404 для клиентских ошибок или 500-503 для серверных ошибок) будет указывать на проблему, которую мы должны обработать соответствующим образом.
  3. Чтение и десериализация токена из тела ответа: Если запрос был успешным (код состояния 200), токен авторизации, как правило, содержится в теле ответа, чаще всего также в формате JSON. Для его извлечения нам необходимо:
    • Прочитать тело ответа как строку, используя метод ПолучитьТелоКакСтроку() объекта Ответ.
    • Десериализовать полученную JSON-строку в объект 1С (Структура, Соответствие, Массив) с помощью объектов ЧтениеJSON и глобальной функции ПрочитатьJSON().
    • Извлечь само значение токена из полученного объекта 1С по соответствующему имени поля (например, "access_token", "token" или "jwt").

Давайте посмотрим, как это реализовать на практике в коде 1С:


// Вся операция отправки запроса и обработки ответа помещается в блок Попытка...Исключение.
// Это позволяет перехватывать и обрабатывать возможные ошибки, например, сетевые проблемы.
Попытка
    // Отправляем сформированный HTTP-запрос через установленное HTTP-соединение.
    Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос);

    // Проверяем код состояния HTTP-ответа. Код 200 обычно означает успешное выполнение.
    Если Ответ.КодСостояния = 200 Тогда
        // Если запрос успешен, читаем тело ответа как строку.
        // Указываем кодировку UTF-8, так как большинство API используют ее.
        ТелоОтветаСтрокой = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);

        // Инициализируем объект ЧтениеJSON для десериализации JSON-строки.
        ЧтениеJSON = Новый ЧтениеJSON;
        // Устанавливаем строку, которую нужно десериализовать.
        ЧтениеJSON.УстановитьСтроку(ТелоОтветаСтрокой);
        // Десериализуем JSON в объект 1С (обычно Структура или Соответствие).
        ДанныеОтвета = ПрочитатьJSON(ЧтениеJSON);

        // Получаем токен доступа из десериализованных данных.
        // Название поля ("access_token") может отличаться в зависимости от API
        // (например, "token", "jwt", "authToken"). Проверьте документацию API.
        ТокенДоступа = ДанныеОтвета.access_token;
        Сообщить("Токен успешно получен: " + ТокенДоступа);
    Иначе
        // Если код состояния не 200, значит, произошла ошибка на стороне сервера или клиента.
        // Выводим код состояния и тело ответа для диагностики.
        Сообщить("Ошибка при получении токена. Код состояния: " + Ответ.КодСостояния);
        Сообщить("Тело ответа с ошибкой: " + Ответ.ПолучитьТелоКакСтроку());
    КонецЕсли;
Исключение
    // Перехватываем общие ошибки выполнения, например, если сервер недоступен.
    Сообщить("Произошла ошибка при отправке запроса: " + ОписаниеОшибки());
КонецПопытки;

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

Альтернативное решение: Использование библиотеки "Connector"

В ходе обсуждения на форуме был предложен еще один весьма эффективный подход к решению подобных задач — использование готовой библиотеки "Connector", доступной на GitHub. Эта библиотека является набором полезных инструментов для работы с HTTP-запросами и другими интеграционными сценариями в 1С. Она может значительно упростить разработку, решая до 99% типичных вопросов, связанных с взаимодействием по HTTP.

Рассмотрим, как мы можем использовать эту библиотеку, особенно если у нас есть ограничения на изменение конфигурации:

  1. Интеграция как внешняя обработка: Если у нас нет возможности или желания изменять основную конфигурацию, мы можем подключить библиотеку "Connector" как внешнюю обработку. Это позволяет использовать весь ее функционал, не внося прямых изменений в конфигурацию. Мы просто открываем внешнюю обработку и вызываем ее экспортные методы из нашего кода. Это обеспечивает высокую гибкость и независимость от обновлений конфигурации.
  2. Использование через расширение конфигурации: Более предпочтительным и современным способом интеграции, особенно в управляемых формах, является включение библиотеки в расширение конфигурации. Этот подход также позволяет избежать изменений основной конфигурации, сохраняя возможность ее штатного обновления. При этом мы можем использовать функционал библиотеки "Connector" непосредственно из кода конфигурации, других расширений или внешних обработок, просто подключив расширение к нашей базе.

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

Дополнительные сценарии и соображения

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

  1. Аутентификация OAuth 2.0: Часто получение токена является частью более сложного протокола аутентификации, такого как OAuth 2.0. Платформа 1С, начиная с версии 8.3.21, включает расширенные возможности для работы с JWT-токенами (JSON Web Tokens), которые являются центральным элементом OAuth 2.0. Изучение этих возможностей может значительно упростить реализацию сложных сценариев авторизации.
  2. Базовая аутентификация (Basic Authentication): Иногда, помимо передачи данных в теле запроса, сервер может требовать и базовую HTTP-аутентификацию. Она устанавливается через заголовок Authorization, где логин и пароль кодируются в Base64. Мы можем добавить такой заголовок к нашему запросу, если это необходимо. Пример: Заголовки.Вставить("Authorization", "Basic " + Base64Строка(Логин + ":" + Пароль));
  3. Обработка ошибок: Мы уже упоминали о важности обработки ошибок, но хотим подчеркнуть это еще раз. Всегда предусматривайте обработку возможных ошибок: недоступность сервера, неверные учетные данные (обычно коды ответа 401, 403), некорректные параметры запроса (код 400) или ошибки на стороне сервера (коды 5xx). Ваши пользователи должны получать понятные сообщения об ошибках, а не видеть системные сбои или непонятные сообщения об исключениях.
  4. Использование внешних инструментов для отладки: Для эффективной отладки HTTP-запросов, как и в случае с Postman, мы можем использовать такие инструменты, как Fiddler или Wireshark. Они позволяют перехватывать и анализировать HTTP-трафик, отправляемый из 1С. Это бесценно для того, чтобы убедиться, что запрос сформирован абсолютно корректно, что заголовки и тело запроса соответствуют ожиданиям сервера, и для диагностики проблем, если сервер возвращает неожиданные ошибки.

Мы подробно разобрали основные шаги и нюансы получения токена авторизации в 1С с передачей логина и пароля в теле запроса. Мы рассмотрели как ручное формирование запроса с помощью стандартных объектов 1С, так и возможность использования готовых библиотек. Надеемся, что эти рекомендации помогут вам успешно интегрировать необходимые сервисы, обеспечить надежное взаимодействие с внешними системами и сделают вашу разработку более эффективной. Для закрепления навыков работы с запросами и заголовками можно использовать интерактивный обучающий курс по HTTP-запросам.

← На главную