Как передать параметры --data-urlencoded и --data из curl в POST-запрос 1С при авторизации в GitLab?

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

При интеграции 1С с внешними системами, такими как GitLab, разработчики часто сталкиваются с необходимостью повторить логику работы готовых скриптов на curl. Одной из неочевидных задач является одновременная передача параметров --data и --data-urlencode. В этой статье мы разберем, как работает механика объединения данных в HTTP-протоколе, как правильно сформировать тело запроса в 1С и решим сопутствующие проблемы с авторизацией и отображением полученного контента.

Разбор механики: как curl объединяет параметры

Для начала проанализируем, что происходит "под капотом" у curl, когда мы указываем несколько флагов передачи данных. Важно понимать, что в стандартном HTTP-запросе тело (body) является единым потоком данных. Согласно официальной документации curl, параметры --data, --data-binary и --data-urlencode не создают разные типы данных в одном запросе. Вместо этого они склеиваются в одну строку через символ амперсанда &.

Разница заключается лишь в предварительной обработке:

Таким образом, для 1С это означает одну простую вещь: нам нужно собрать единую строку тела запроса, где каждая часть подготовлена соответствующим образом. Рассмотрим, как это реализовать программно.

Шаг 1: Формирование заголовков и подготовка данных

Выясним причину, по которой сервер может отвергать запрос. Чаще всего это неправильный заголовок Content-Type. Для имитации формы авторизации (которую и делает curl с этими флагами), необходимо использовать application/x-www-form-urlencoded. В этом случае все данные передаются как пары "ключ=значение".

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

Посмотрим на пример кода для подготовки строки тела:


// Определяем значения
Логин = "gitlab_user";
Пароль = "super_password#123"; // Символ # требует кодирования
Токен = "dG9rZW4rZGF0YQ=="; // Пример токена с символами + и =

// Кодируем параметры, которые могут содержать спецсимволы
// Используем URLУмеренное для сохранения структуры ключей
ЗакодированныйПароль = КодироватьСтроку(Пароль, СпособКодированияСтроки.URLУмеренное);
ЗакодированныйТокен = КодироватьСтроку(Токен, СпособКодированияСтроки.URLУмеренное);

// Собираем итоговое тело запроса (аналог склейки в curl)
ТелоЗапроса = "user[login]=" + Логин + 
               "&user[password]=" + ЗакодированныйПароль + 
               "&authenticity_token=" + ЗакодированныйТокен;

Шаг 2: Выполнение HTTP-запроса в 1С

Рассмотрим подробнее процесс отправки. Нам потребуется объект HTTPЗапрос. Важно помнить, что если вы используете LDAP-авторизацию, сервер ожидает не только тело, но и куки (cookies), полученные при первом обращении к странице логина.


// Создаем соединение
НТТРСоединение = Новый HTTPСоединение("gitlab.example.com", , , , , , Новый ЗащищенноеСоединениеOpenSSL());

// Создаем запрос
Запрос = Новый HTTPЗапрос("/users/sign_in");

// Устанавливаем обязательный заголовок
Запрос.Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");

// Если у нас есть куки из предыдущего GET-запроса, добавляем их
// Куки обычно передаются в заголовке "Cookie"
Запрос.Заголовки.Вставить("Cookie", "session_id=...; _gitlab_session=...");

// Устанавливаем сформированное тело
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);

// Отправляем POST-запрос
Ответ = НТТРСоединение.ОтправитьДляОбработки(Запрос);

Обратите внимание на вопрос о Base64, который часто возникает у разработчиков (сообщение 1 темы). При использовании стандартных веб-форм Base64 не применяется для полей логина и пароля. Данные передаются в открытом (но URL-закодированном) виде. Безопасность обеспечивается самим протоколом HTTPS, который шифрует весь трафик.

Шаг 3: Реализация последовательной авторизации (LDAP/Web)

Проанализируем ситуацию: для успешного входа в GitLab через веб-интерфейс (не API) недостаточно одного запроса. Нужно выполнить цепочку действий, которую автор темы успешно реализовал в сообщении 14:

  1. Первый GET-запрос: Обращаемся к странице /users/sign_in. Из заголовков ответа (Set-Cookie) сохраняем сессионные куки. Из тела ответа (HTML) извлекаем значение скрытого поля authenticity_token.
  2. Второй POST-запрос: Отправляем данные авторизации, как мы разобрали выше, обязательно прикладывая куки и токен из первого шага. В ответ сервер должен прислать код состояния 302 (перенаправление) и новые куки авторизованной сессии.
  3. Третий GET-запрос: Запрашиваем нужную нам страницу (например, страницу коммита), используя куки, полученные на втором шаге.

Шаг 4: Решение проблемы с отображением HTML в 1С

Часто после успешного получения HTML-кода страницы при помощи ПолучитьТелоКакСтроку(), разработчики сталкиваются с тем, что в поле HTML-документа на форме 1С страница "разваливается": пропадают стили, картинки и скрипты (сообщение 14). Выясним причину: это происходит из-за относительных путей в коде GitLab.

В HTML коде ссылки на стили выглядят как /assets/application.css. Поле HTML-документа 1С пытается найти их на локальном диске или по адресу, который ему неизвестен. Чтобы это исправить, выполним одно из следующих действий:

Пример программной правки HTML перед выводом на форму:


ТекстHTML = Ответ.ПолучитьТелоКакСтроку();
// Вставляем базовый URL для корректной загрузки стилей и скриптов
ТекстHTML = СтрЗаменить(ТекстHTML, "<head>", "<head><base href=""https://gitlab.mycompany.ru/"">");
Элементы.ПолеHTMLПросмотра.УстановитьТекст(ТекстHTML);

Таким образом, мы разобрали, что "совмещение" разных параметров данных в 1С сводится к правильной конкатенации строки и ручному URL-кодированию чувствительных частей данных. Этот подход универсален и применим не только к GitLab, но и к любым веб-сервисам, требующим авторизации через формы.

← На главную