При начале работы с API СДЭК версии 2.0 многие разработчики сталкиваются с проблемой получения первичного токена доступа. Даже при наличии верных идентификаторов Account (client_id) и Secure password (client_secret), сервер может возвращать ошибку 401 Unauthorized. В данной статье мы подробно разберем, как правильно настроить POST-запрос в 1С, какие заголовки необходимо передать и в каком формате подготовить тело запроса, чтобы успешно пройти авторизацию.
Рассмотрим ситуацию: разработчик пытается отправить данные для получения токена, упаковывая их в формат JSON, и устанавливает заголовок Content-Type как application/javascript или application/json. Однако протокол OAuth 2.0, который использует СДЭК, требует передачи параметров в формате x-www-form-urlencoded. Это означает, что данные должны передаваться не в виде структуры JSON, а в виде строки ключ-значение, разделенных амперсандом.
Выясним основную причину неудачи: сервер СДЭК ожидает, что параметры grant_type, client_id и client_secret будут закодированы как параметры URL в теле POST-запроса. Если отправить их в JSON, парсер на стороне сервера просто не увидит учетных данных и вернет ошибку авторизации.
Для начала нам необходимо создать объект HTTPЗапрос и указать верный тип контента. Вместо привычного JSON мы должны использовать специфический заголовок. Разберем по шагам, как это выглядит в коде:
// Создаем соответствие для заголовков
Заголовки = Новый Соответствие;
// Важно: указываем именно этот тип контента
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
// Создаем объект запроса
Запрос = Новый HTTPЗапрос(СтруктураAPI.Путь, Заголовки);
Также стоит отметить, что некоторые серверы (включая инфраструктуру Atlassian, на которой построена документация СДЭК) могут требовать явного указания заголовка Content-Length. Хотя 1С часто вычисляет его автоматически, в спорных ситуациях его стоит проверить.
Теперь перейдем к самой важной части — подготовке строки с параметрами. Мы не можем просто передать структуру. Нам нужно собрать строку вида: ключ1=значение1&ключ2=значение2. Проанализируем, как правильно реализовать это в 1С, учитывая необходимость кодирования спецсимволов.
Рассмотрим функцию, которая преобразует параметры авторизации в нужный формат:
Функция СформироватьТелоЗапроса(Идентификатор, Пароль)
// Параметры для OAuth СДЭК
ТипГранта = "client_credentials";
// Собираем строку параметров
// Важно: значения должны быть закодированы для URL
СтрокаПараметров = "grant_type=" + ТипГранта +
"&client_id=" + КодироватьСтроку(Идентификатор, СпособКодированияСтроки.URLКодирование) +
"&client_secret=" + КодироватьСтроку(Пароль, СпособКодированияСтроки.URLКодирование);
Возврат СтрокаПараметров;
КонецФункции
Обратите внимание на использование функции КодироватьСтроку. Если ваш секретный пароль содержит символы вроде "+", "/" или "=", без URL-кодирования запрос будет отклонен сервером как некорректный.
Соберем все части воедино. При отправке данных методом УстановитьТелоИзСтроки крайне рекомендуется явно указывать кодировку UTF-8 и отключать использование BOM (Byte Order Mark), так как лишние невидимые символы в начале строки могут привести к ошибке разбора на стороне API.
Посмотрим на итоговый пример реализации процедуры получения токена:
Процедура ПолучитьТокенСДЭК()
Сервер = "api.edu.cdek.ru"; // Тестовый сервер
Ресурс = "/v2/oauth/token";
// Учетные данные (замените на свои или тестовые из документации)
Идентификатор = "EMscd6r9JnFiQ3bLoyjJY6eM78JrJceI";
Пароль = "PjLZkKBHEiLK3YsjtNrt3TGNG0ahs3kG";
// Настройка защищенного соединения
Защита = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(Сервер, 443, , , , , Защита);
// Формируем заголовки
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
// Формируем тело
ТелоЗапроса = "grant_type=client_credentials&client_id=" + Идентификатор + "&client_secret=" + Пароль;
Запрос = Новый HTTPЗапрос(Ресурс, Заголовки);
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
Попытка
Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);
ОтветСтрокой = Ответ.ПолучитьТелоКакСтроку();
Если Ответ.КодСостояния = 200 Тогда
// Успех! Парсим JSON с токеном
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ОтветСтрокой);
ДанныеОтвета = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
ТокенДоступа = ДанныеОтвета.access_token;
Сообщить("Токен успешно получен: " + ТокенДоступа);
Иначе
Сообщить("Ошибка! Код состояния: " + Ответ.КодСостояния);
Сообщить("Текст ответа: " + ОтветСтрокой);
КонецЕсли;
Исключение
Сообщить("Ошибка связи с сервером: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Рассмотрим несколько дополнительных моментов, которые помогут сделать вашу интеграцию стабильной и эффективной:
Кэширование токена
Полученный access_token имеет ограниченный срок жизни (обычно 24 часа). В ответе сервера это время указано в секундах в поле expires_in. Не запрашивайте токен перед каждым вызовом API (расчетом стоимости или созданием заказа). Правильнее всего будет сохранить токен в константу или в параметры сеанса вместе с датой его истечения. Запрашивайте новый токен только тогда, когда срок действия текущего подходит к концу. Это избавит вас от лишних сетевых задержек и риска блокировки по IP за слишком частую авторизацию.
Разделение сред
Помните, что тестовая среда (api.edu.cdek.ru) и боевая среда (api.cdek.ru) полностью изолированы. Учетные данные от боевого личного кабинета не будут работать на тестовом сервере, и наоборот. Всегда проверяйте, какой адрес сервера используется в объекте HTTPСоединение.
Использование токена в последующих запросах
После того как вы получили токен, его нужно передавать в каждом последующем запросе к методам API (например, для получения списка ПВЗ или создания накладной). Это делается через заголовок Authorization. Формат значения должен быть следующим: Bearer [ваш_токен].
Пример добавления токена в заголовок следующего запроса:
Заголовки.Вставить("Authorization", "Bearer " + СохраненныйТокен);
Следуя этим правилам и используя приведенный выше код, вы сможете успешно интегрировать вашу базу 1С с сервисами доставки СДЭК, избежав распространенных ошибок авторизации.