Как получить токен авторизации API СДЭК v2.0 в 1С и исправить ошибку 401 Unauthorized

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

При начале работы с 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, парсер на стороне сервера просто не увидит учетных данных и вернет ошибку авторизации.

Шаг 1. Настройка правильных заголовков HTTP-запроса

Для начала нам необходимо создать объект HTTPЗапрос и указать верный тип контента. Вместо привычного JSON мы должны использовать специфический заголовок. Разберем по шагам, как это выглядит в коде:


// Создаем соответствие для заголовков
Заголовки = Новый Соответствие;
// Важно: указываем именно этот тип контента
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");

// Создаем объект запроса
Запрос = Новый HTTPЗапрос(СтруктураAPI.Путь, Заголовки);

Также стоит отметить, что некоторые серверы (включая инфраструктуру Atlassian, на которой построена документация СДЭК) могут требовать явного указания заголовка Content-Length. Хотя 1С часто вычисляет его автоматически, в спорных ситуациях его стоит проверить.

Шаг 2. Формирование тела запроса в формате x-www-form-urlencoded

Теперь перейдем к самой важной части — подготовке строки с параметрами. Мы не можем просто передать структуру. Нам нужно собрать строку вида: ключ1=значение1&ключ2=значение2. Проанализируем, как правильно реализовать это в 1С, учитывая необходимость кодирования спецсимволов.

Рассмотрим функцию, которая преобразует параметры авторизации в нужный формат:


Функция СформироватьТелоЗапроса(Идентификатор, Пароль)
    
    // Параметры для OAuth СДЭК
    ТипГранта = "client_credentials";
    
    // Собираем строку параметров
    // Важно: значения должны быть закодированы для URL
    СтрокаПараметров = "grant_type=" + ТипГранта + 
                       "&client_id=" + КодироватьСтроку(Идентификатор, СпособКодированияСтроки.URLКодирование) + 
                       "&client_secret=" + КодироватьСтроку(Пароль, СпособКодированияСтроки.URLКодирование);
                       
    Возврат СтрокаПараметров;
    
КонецФункции

Обратите внимание на использование функции КодироватьСтроку. Если ваш секретный пароль содержит символы вроде "+", "/" или "=", без URL-кодирования запрос будет отклонен сервером как некорректный.

Шаг 3. Отправка POST-запроса и обработка результата

Соберем все части воедино. При отправке данных методом УстановитьТелоИзСтроки крайне рекомендуется явно указывать кодировку 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;
            Сообщить("Токен успешно получен: " + ТокенДоступа);
        Иначе
            Сообщить("Ошибка! Код состояния: " + Ответ.КодСостояния);
            Сообщить("Текст ответа: " + ОтветСтрокой);
        КонецЕсли;
    Исключение
        Сообщить("Ошибка связи с сервером: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Важные нюансы работы с API СДЭК

Рассмотрим несколько дополнительных моментов, которые помогут сделать вашу интеграцию стабильной и эффективной:

Кэширование токена

Полученный access_token имеет ограниченный срок жизни (обычно 24 часа). В ответе сервера это время указано в секундах в поле expires_in. Не запрашивайте токен перед каждым вызовом API (расчетом стоимости или созданием заказа). Правильнее всего будет сохранить токен в константу или в параметры сеанса вместе с датой его истечения. Запрашивайте новый токен только тогда, когда срок действия текущего подходит к концу. Это избавит вас от лишних сетевых задержек и риска блокировки по IP за слишком частую авторизацию.

Разделение сред

Помните, что тестовая среда (api.edu.cdek.ru) и боевая среда (api.cdek.ru) полностью изолированы. Учетные данные от боевого личного кабинета не будут работать на тестовом сервере, и наоборот. Всегда проверяйте, какой адрес сервера используется в объекте HTTPСоединение.

Использование токена в последующих запросах

После того как вы получили токен, его нужно передавать в каждом последующем запросе к методам API (например, для получения списка ПВЗ или создания накладной). Это делается через заголовок Authorization. Формат значения должен быть следующим: Bearer [ваш_токен].

Пример добавления токена в заголовок следующего запроса:

Заголовки.Вставить("Authorization", "Bearer " + СохраненныйТокен);

Следуя этим правилам и используя приведенный выше код, вы сможете успешно интегрировать вашу базу 1С с сервисами доставки СДЭК, избежав распространенных ошибок авторизации.

← На главную