В процессе интеграции 1С с внешними веб-сервисами разработчики часто сталкиваются с ситуацией, когда стандартное HTTPСоединение отказывается работать. Чаще всего это проявляется в виде ошибки 401 Unauthorized или системных сообщений о невалидности SSL-сертификата. В данной статье мы подробно разберем, диагностировать эти проблемы и какие инструменты предоставляет платформа 1С для их решения.
Прежде чем переходить к коду, проанализируем ситуацию. Ошибка 401 означает, что сервер отклонил ваши учетные данные или способ их передачи. Ошибки SSL (например, "Certificate has expired") говорят о том, что защищенный канал связи не может быть установлен из-за проблем с безопасностью на стороне сервера или клиента.
Основные причины проблем:
Cookie или специальных токенов после первого запроса.Если вы столкнулись с ситуацией, когда сертификат на стороне сервера просрочен (как выяснилось в ходе обсуждения проблемы в сообщении 18), но подключиться необходимо, мы можем настроить 1С на игнорирование этой ошибки. Начиная с версии платформы 8.3.10, для этого используются специальные параметры проверки.
Рассмотрим пример кода, который позволяет установить соединение даже с «проблемным» сертификатом:
// Создаем параметры проверки, отключающие строгий контроль
ПараметрыПроверки = Новый ПараметрыПроверкиСертификатаСервераOpenSSL();
ПараметрыПроверки.ПроверкаСертификатаСервера = ПроверкаСертификатаСервераOpenSSL.НеПроверять;
// Инициализируем защищенное соединение с этими параметрами
// Первый параметр (СертификатКлиента) оставляем Неопределено, если mTLS не требуется
СоединениеOpenSSL = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, ПараметрыПроверки);
// Создаем HTTPСоединение
Соединение = Новый HTTPСоединение("api.site.ru", , , , , , СоединениеOpenSSL);
Важно: Метод ПроверкаСертификатаСервераOpenSSL.НеПроверять следует использовать только в отладочных целях или для внутренних сервисов, где вы полностью доверяете источнику данных.
Часто ошибка 401 возникает из-за того, что разработчик пытается передать логин и пароль прямо в тексте запроса, например: /api/login?user=admin&pass=123. Современные API требуют использования заголовков запроса.
Проанализируем стандарт Basic Authorization. Нам нужно сформировать строку вида "Логин:Пароль", закодировать ее в Base64 и добавить в заголовки HTTPЗапрос. Посмотрим на реализацию:
// Формируем строку авторизации
Логин = "User";
Пароль = "12345";
СтрокаАвторизации = Логин + ":" + Пароль;
// Кодируем в Base64 (используем средства 1С)
ДвоичныеДанныеСтроки = ПолучитьДвоичныеДанныеИзСтроки(СтрокаАвторизации, КодировкаТекста.UTF8, Ложь);
Base64Значение = Base64Строка(ДвоичныеДанныеСтроки);
// Очищаем от возможных символов переноса строки
Base64Значение = СтрЗаменить(Base64Значение, Символы.ПС, "");
Base64Значение = СтрЗаменить(Base64Значение, Символы.ВК, "");
// Создаем запрос и добавляем заголовок
ЗапросHTTP = Новый HTTPЗапрос("/api/v1/data");
ЗапросHTTP.Заголовки.Вставить("Authorization", "Basic " + Base64Значение);
Ответ = Соединение.Получить(ЗапросHTTP);
Если первый запрос (логин) проходит успешно, а последующие возвращают 401, значит сервер «не узнает» вас. В браузере это решается автоматически через Cookie, но в 1С нам нужно делать это вручную.
Выясним причину: после авторизации сервер присылает заголовок Set-Cookie. Мы должны прочитать его и подставить во все следующие запросы в рамках этого сеанса.
// 1. Выполняем запрос авторизации
ОтветЛогин = Соединение.Получить(ЗапросЛогин);
// 2. Извлекаем куки из ответа
ВсеКуки = ОтветЛогин.Заголовки.Получить("Set-Cookie");
Если ВсеКуки <> Неопределено Тогда
// 3. Создаем новый запрос к данным и передаем полученные куки
ЗапросДанных = Новый HTTPЗапрос("/api/v1/secure-data");
ЗапросДанных.Заголовки.Вставить("Cookie", ВсеКуки);
ОтветДанные = Соединение.Получить(ЗапросДанных);
КонецЕсли;
В некоторых случаях (особенно в старых версиях платформы или при специфических настройках прокси) стандартные средства 1С могут не справляться. Тогда можно воспользоваться объектом WinHttp.WinHttpRequest.5.1. Он позволяет тонко настраивать параметры TLS и игнорировать ошибки сертификации через метод setOption.
Рассмотрим, как проигнорировать все ошибки SSL (аналог отключения проверки в Postman):
// Инициализация COM-объекта
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("GET", "https://api.site.ru/data", Ложь);
// Опция 4: SslErrorIgnoreFlags. Значение 0x3300 или 13056 игнорирует большинство ошибок
// (истекший срок, неправильное имя узла, самоподписанный сертификат)
WinHttp.Option(4, 13056);
WinHttp.Send();
Статус = WinHttp.Status;
ТекстОтвета = WinHttp.ResponseText;
Если для подключения требуется файл сертификата (формат .pem или .pfx), убедитесь, что в файле присутствует закрытый ключ. При использовании конструктора СертификатКлиентаФайл в 1С, вы должны предоставить путь к файлу на диске. Если код выполняется на сервере 1С, убедитесь, что у пользователя, под которым запущена служба usr1cv8, есть права доступа к этому файлу.
Подводя итог, отметим: если вы получаете ошибку 401 при работе с API, первым делом проверьте корректность передачи заголовка Authorization и обработку Cookie. Если же соединение обрывается еще до получения ответа — анализируйте валидность SSL-сертификата и при необходимости используйте программное отключение проверки в объекте ЗащищенноеСоединениеOpenSSL.