При интеграции 1С с логистическим сервисом СДЭК по протоколу API v2.0 разработчики часто сталкиваются с ошибкой 401 Unauthorized при попытке получить авторизационный токен. Проблема коварна тем, что даже при наличии верных клиентских ключей (client_id и client_secret), сервер может отклонять запрос из-за мелких неточностей в оформлении HTTP-заголовков или неправильного кодирования тела запроса. В рамках этой статьи мы подробно разберем, как правильно реализовать механизм OAuth 2.0 в 1С, проанализируем типичные ошибки и составим эталонный код для подключения.
Для начала выясним причину, по которой СДЭК возвращает статус 401. Согласно протоколу OAuth 2.0, авторизация клиента происходит через POST-запрос. Ошибка «Unauthorized» в данном контексте обычно означает одно из трех:
application/x-www-form-urlencoded. Если указать просто x-www-form-urlencoded или application/json, данные в теле запроса не будут корректно распознаны.Account и Secure password, полученных в разделе «Интеграция».Рассмотрим процесс создания объекта HTTPСоединение. СДЭК работает исключительно по защищенному протоколу TLS 1.2. В 1С это обеспечивается инициализацией объекта ЗащищенноеСоединениеOpenSSL. Если вы используете старую версию платформы (ниже 8.3.12), могут возникнуть проблемы с совместимостью протоколов шифрования, поэтому всегда рекомендуется использовать актуальные релизы.
Проанализируем формирование структуры заголовков. Важным моментом является точное указание типа контента. Рассмотрим пример кода для создания запроса:
// Настройка защищенного соединения
Защита = Новый ЗащищенноеСоединениеOpenSSL();
// Создание соединения с сервером (боевой или тестовый адрес)
// Тестовый: api.edu.cdek.ru, Боевой: api.cdek.ru
Соединение = Новый HTTPСоединение("api.edu.cdek.ru", 443, , , , , Защита);
// Установка заголовков
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
Для получения токена нам необходимо передать три параметра: grant_type (всегда client_credentials), client_id и client_secret. Распространенная ошибка — передача этих данных в строке URL (после знака вопроса). Хотя некоторые серверы это допускают, стандарт требует передачи данных именно в теле POST-запроса.
Посмотрим на пример правильного формирования строки параметров. Обратите внимание, что мы используем ИспользованиеByteOrderMark.НеИспользовать, так как наличие BOM-символов в начале строки может сбить с толку парсер на стороне СДЭК.
// Формируем строку параметров
ПараметрыСтрокой = "grant_type=client_credentials&client_id=" + ЛогинAPI + "&client_secret=" + ПарольAPI;
// Создаем объект HTTPЗапрос
ПутьКТокену = "/v2/oauth/token";
Запрос = Новый HTTPЗапрос(ПутьКТокену, Заголовки);
// Устанавливаем тело запроса
Запрос.УстановитьТелоИзСтроки(ПараметрыСтрокой, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Выясним причину, по которой ручное кодирование всей строки функцией КодироватьСтроку может привести к ошибке. Если вы примените кодирование к строке grant_type=client_credentials, символ «=» превратится в %3D, и сервер СДЭК не сможет выделить имя ключа. Кодировать нужно только те значения, которые могут содержать спецсимволы (например, если в вашем секретном ключе есть знак «+» или «&»).
Разберем, как правильно обрабатывать полученный ответ. Сервер возвращает JSON, содержащий access_token и expires_in (время жизни токена в секундах).
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
КодСостояния = Ответ.КодСостояния;
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
Если КодСостояния = 200 Тогда
// Чтение JSON
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТелоОтвета);
ДанныеТокена = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Токен = ДанныеТокена.access_token;
Сообщить("Авторизация успешна. Токен получен.");
Иначе
Сообщить("Ошибка авторизации! Код: " + КодСостояния + ". Ответ: " + ТелоОтвета);
КонецЕсли;
Исключение
Сообщить("Ошибка сетевого соединения: " + ОписаниеОшибки());
КонецПопытки;
После того как мы успешно получили токен, важно правильно его использовать в дальнейшей работе. Рассмотрим несколько критических моментов:
ПараметрыСеанса или в специальную константу вместе с временем его истечения. Запрашивайте новый только тогда, когда старый близок к истечению. Это поможет избежать блокировки вашего IP за избыточное количество запросов к сервису авторизации.api.edu.cdek.ru. Ключи для тестов:client_id: z99nVpNb6D6uS6iC0O64Mh8J581335T1client_secret: P8vVv5uTjZ03vP2sL2u9S6sE55Z451Authorization со значением Bearer [ваш_токен]. Также не забудьте изменить Content-Type на application/json для рабочих запросов.Проанализировав ситуацию, мы видим, что основная сложность интеграции со СДЭК заключается в строгом соблюдении стандартов OAuth 2.0 и правильном заполнении HTTP-контейнера. Использование вышеприведенного кода позволит вам быстро наладить обмен данными и избежать досадных ошибок авторизации.