Как реализовать HTTPS-запрос с авторизацией в 1С 8.1 через WinHttp.WinHttpRequest.5.1

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

При работе в старых версиях платформы (например, 1С 8.1 или ранних сборках 8.3 на обычных формах) разработчики часто сталкиваются с тем, что штатный объект HTTPСоединение некорректно обрабатывает современные протоколы безопасности HTTPS. Это приводит к получению пустых ответов или ошибкам соединения. В такой ситуации на помощь приходит системный COM-объект WinHttp.WinHttpRequest.5.1. В этой статье мы подробно разберем, как настроить авторизацию, обойти проблемы с сертификатами и заставить 1С успешно обмениваться данными с современными сайтами.

Почему штатные средства 1С 8.1 не справляются с HTTPS

Основная причина кроется в том, что платформа 8.1 разрабатывалась в эпоху, когда стандарты безопасности были иными. Современные веб-серверы требуют использования протоколов TLS 1.2 или TLS 1.3, в то время как старые компоненты Windows и 1С по умолчанию пытаются использовать SSL 3.0 или TLS 1.0. Кроме того, механизм работы с сертификатами в 8.1 требует их обязательной прописки в файл cacert.pem, что не всегда гарантирует успех. Использование WinHttp.WinHttpRequest.5.1 позволяет делегировать работу с сетевым уровнем операционной системе, что значительно упрощает задачу.

Решение 1: Использование метода SetCredentials для стандартной авторизации

Метод SetCredentials предназначен для обработки стандартного «рукопожатия» (handshake). Рассмотрим, как правильно инициализировать объект и отправить POST-запрос с данными авторизации. Проанализируем пример кода, который позволяет передать логин и пароль серверу:


Процедура ВыполнитьЗапросКСерверу()
    Сервер = "example.com";
    Ресурс = "/api/v1/data";
    
    // Создаем объект WinHttp
    Попытка
        WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
    Исключение
        Сообщить("Не удалось создать объект WinHttp: " + ОписаниеОшибки());
        Возврат;
    КонецПопытки;

    // Устанавливаем кодировку для работы с кириллицей, если необходимо
    WinHttp.Option(2, "Windows-1251"); 

    // Открываем соединение (0 - синхронный режим, 1 - асинхронный)
    WinHttp.Open("POST", "https://" + Сервер + Ресурс, 0);

    // Указываем данные для авторизации (0 - для сервера, 1 - для прокси)
    // Важно: этот метод часто срабатывает только ПОСЛЕ того, как сервер вернет 401 ошибку
    WinHttp.SetCredentials("ВашЛогин", "ВашПароль", 0);

    Попытка
        WinHttp.Send("Данные запроса");
        
        Если WinHttp.Status = 200 Тогда
            Результат = WinHttp.ResponseText;
            Сообщить("Данные получены успешно!");
        Иначе
            Сообщить("Ошибка сервера. Статус: " + WinHttp.Status + " " + WinHttp.StatusText);
        КонецЕсли;
    Исключение
        Сообщить("Ошибка при отправке запроса: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Решение 2: Ручное формирование заголовка Authorization (Basic Auth)

Иногда метод SetCredentials не срабатывает из-за особенностей настройки веб-сервера (если он не отправляет заголовок WWW-Authenticate). В этом случае мы можем принудительно передать данные авторизации в заголовке запроса. Для этого нам нужно закодировать строку «Логин:Пароль» в формат Base64.

Выясним причину, почему в 1С 8.1 это сделать сложнее: встроенной функции Base64Строка для обычных строк там нет. Приходится использовать временные файлы или дополнительные COM-объекты.


Функция ПолучитьЗаголовокАвторизации(Логин, Пароль)
    СтрокаАвторизации = СокрЛП(Логин) + ":" + СокрЛП(Пароль);
    
    // В 8.1 приходится использовать обходной путь через временный файл
    ИмяФайла = ПолучитьИмяВременногоФайла();
    ТекстДок = Новый ТекстовыйДокумент;
    ТекстДок.ДобавитьСтроку(СтрокаАвторизации);
    // Важно: серверы обычно ждут кодировку ANSI/ISO-8859-1 для Basic Auth
    ТекстДок.Записать(ИмяФайла, "windows-1251"); 
    
    ДвоичныеДанные = Новый ДвоичныеДанные(ИмяФайла);
    РезультатBase64 = Base64Строка(ДвоичныеДанные);
    
    // Удаляем перенос строки, который 1С может добавить в Base64
    РезультатBase64 = СтрЗаменить(РезультатBase64, Символы.ПС, "");
    РезультатBase64 = СтрЗаменить(РезультатBase64, Символы.ВК, "");
    
    УдалитьФайлы(ИмяФайла);
    
    Возврат "Basic " + РезультатBase64;
КонецФункции

Процедура СделатьЗапросРучнойАвторизации()
    WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
    WinHttp.Open("GET", "https://mysite.ru/info", 0);
    
    Заголовок = ПолучитьЗаголовокАвторизации("admin", "p@ssword");
    WinHttp.SetRequestHeader("Authorization", Заголовок);
    
    WinHttp.Send();
    Сообщить(WinHttp.ResponseText);
КонецПроцедуры

Настройка TLS 1.2 и игнорирование ошибок сертификатов

Проанализируем ситуацию: вы написали код, логин и пароль верны, но запрос обрывается с ошибкой «The connection with the server was terminated abnormally». Это верный признак проблем с протоколом TLS. Посмотрим, как принудительно включить поддержку TLS 1.2 через свойства объекта Option.

Существует параметр Option(9) (SecureProtocols). По умолчанию он может быть настроен на старые протоколы. Чтобы включить поддержку TLS 1.2, используем значение 2048. Если нужно поддерживать и TLS 1.1, и TLS 1.2, можно установить значение 2560.

Также разберем ситуацию с сертификатами. Если сервер использует самоподписанный сертификат, WinHttp заблокирует запрос. Чтобы проигнорировать ошибки проверки (истекший срок, неверное имя узла), используем Option(4):


// 2048 - принудительный TLS 1.2
WinHttp.Option(9, 2048); 

// 13056 - сумма флагов для игнорирования всех ошибок сертификатов SSL
// (Unknown CA, Invalid CN, Expired, etc.)
WinHttp.Option(4, 13056); 

Важные нюансы при работе с WinHttp

  1. Тайм-ауты: Чтобы ваша программа не «зависала» при плохом соединении, всегда устанавливайте лимиты ожидания методом SetTimeouts(Resolve, Connect, Send, Receive). Время указывается в миллисекундах.
  2. Получение бинарных данных: Если сайт возвращает не текст, а, например, PDF-файл или картинку, не используйте ResponseText. Это повредит данные. Используйте WinHttp.ResponseBody для получения массива байтов.
  3. Прокси-сервер: Если компьютер клиента работает через прокси, WinHttp может не увидеть его автоматически. В этом случае используйте метод SetProxy(2, "ip:порт").
  4. Кириллица в логине: Как отмечали коллеги на форуме, крайне желательно, чтобы логин и пароль были на английском языке. Работа с кодировками в заголовках HTTP — это всегда риск получить ошибку 401 из-за неверной интерпретации символов сервером.

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

← На главную