Имя: Пароль:
1C
1С v8
Работа с API СДЭК
0 VitaliyTokarev
 
10.04.21
20:35
Итак, проблема. С API до этого с нуля не работал. POST запросы тоже сам не делал ))))
Собираю информацию по крупицам. Почитал про API на сайте:
https://confluence.cdek.ru/pages/viewpage.action?pageId=29923918

Отправляю запрос
grant_type: тип аутентификации, доступное значение: client_credentials;
client_id: идентификатор клиента, равен Account;
client_secret: секретный ключ клиента, равен Secure password.

Id и пароль дали правильные, но в ответ приходит вот что:

{"timestamp":"2021-04-10T16:59:07.618+00:00","status":401,"error":"Unauthorized","message":"","path":"/oauth/token"}

А должен быть токен.
Помогите разобраться что я не так делаю.

Код ниже:

Процедура POSTЗапросИз1С(Команда) Экспорт
    
    Тестовая = Ложь;
    ТипДоступа = 1;
    Если Команда.Имя = "СДЭК_API_Тест_ИМ" Тогда
        Тестовая = Истина;
        ТипДоступа = 1;
    ИначеЕсли Команда.Имя = "СДЭК_API_Тест_Доставка" Тогда
        Тестовая = Истина;
        ТипДоступа = 2;
    КонецЕсли;
    СтруктураAPI = ПутьAPIТестовый();
    ПараметрыЗапроса = ПолучитьПараметрыАвторизации(Тестовая, ТипДоступа);
    HTTPМетод = "POST";
    Соединение = Новый HTTPСоединение(СтруктураAPI.Сервер, СтруктураAPI.Порт, , , , , Новый ЗащищенноеСоединениеOpenSSL);
    Заголовки = Новый Соответствие;
    Заголовки.Вставить("Content-Type", "application/javascript");
    //vvv Здесь пытался вставить параметры, тоже не помогло
    //Для Каждого Параметр Из ПараметрыЗапроса Цикл
    //    Заголовки.Вставить(Параметр.Ключ, Параметр.Значение);
    //КонецЦикла;
    //^^^ Здесь пытался вставить параметры, тоже не помогло
    Запрос = Новый HTTPЗапрос(СтруктураAPI.Путь, Заголовки);
    Запрос.Заголовки.Вставить("Content-Type", "application/javascript");
    Запрос.УстановитьТелоИзСтроки(СтруктураВJson(ПараметрыЗапроса));
    Ответ = Соединение.ВызватьHTTPМетод(HTTPМетод, Запрос);
    ОтветСтрокой = Ответ.ПолучитьТелоКакСтроку();
    ЧтениеJSON = Новый ЧтениеJSON;
    ЧтениеJSON.УстановитьСтроку(ОтветСтрокой);
    Структура = ЗаполнитьСтруктуруИзОтветаJSON(ЧтениеJSON);    
    ЧтениеJSON.Закрыть();    
    
КонецПроцедуры

//ТипДоступа = 1 - Интернет-магазин, 2 - Доставка
Функция Идентификатор(Тестовая = Истина, ТипДоступа = 1)
    Если Тестовая Тогда
        Если ТипДоступа = 1 Тогда
            Возврат "EMscd6r9JnFiQ3bLoyjJY6eM78JrJceI";
        Иначе
            Возврат "7JM7K5twfzEV1ssCRklthcIPbbVZrZrZ";
        КонецЕсли;
    Иначе
        Возврат "nuPLQqOxivwEoJsUv9zBwLlHABTS90Ce";
    КонецЕсли;
КонецФункции

//ТипДоступа = 1 - Интернет-магазин, 2 - Доставка
Функция Пароль(Тестовая = Истина, ТипДоступа = 1)
    Если Тестовая Тогда
        Если ТипДоступа = 1 Тогда
            Возврат "PjLZkKBHEiLK3YsjtNrt3TGNG0ahs3kG";
        Иначе
            Возврат "t8XBoL1rUofIK9dKoXVB3Tji2F2hPHSk";
        КонецЕсли;
    Иначе
        Возврат "tox9HOR42tjDolb93hqSTYxQXOiAmqfX";
    КонецЕсли;
КонецФункции

Функция ПутьНаСервере()
    Возврат "";
КонецФункции

Функция ПутьAPIТестовый()
    Структура = Новый Структура;
    Структура.Вставить("ПолныйПуть", "https://api.edu.cdek.ru/v2/oauth/token?parameters");
    Структура.Вставить("Сервер", "api.edu.cdek.ru");
    Структура.Вставить("Порт", 443);
    Структура.Вставить("Путь", "/v2/oauth/token?parameters");
    Возврат Структура;
КонецФункции

Функция ПутьAPI()
    Структура = Новый Структура;
    Структура.Вставить("ПолныйПуть", "https://api.cdek.ru/v2/oauth/token?parameters");
    Структура.Вставить("Сервер", "api.cdek.ru");
    Структура.Вставить("Порт", 443);
    Структура.Вставить("Путь", "/v2/oauth/token?parameters");
    Возврат Структура;
КонецФункции

//ТипДоступа = 1 - Интернет-магазин, 2 - Доставка
Функция ПолучитьПараметрыАвторизации(Тестовая = Истина, ТипДоступа = 1)
    Структура = Новый Структура;
    Структура.Вставить("grant_type", "client_credentials");
    Структура.Вставить("client_id", Идентификатор(Тестовая, ТипДоступа));
    Структура.Вставить("client_secret", Пароль(Тестовая ,ТипДоступа));
    Возврат Структура;
КонецФункции

Функция СтруктураВJson(Объект) Экспорт
    НастройкиСериализации = Новый НастройкиСериализацииJSON();
    НастройкиСериализации.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.УниверсальнаяДата;
    НастройкиСериализации.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, Объект, НастройкиСериализации);
    
    Возврат ЗаписьJSON.Закрыть();
    
КонецФункции

Функция ЗаполнитьСтруктуруИзОтветаJSON(Знач Чтение) Экспорт
    
    Результат = Новый Структура;

    ПоследнееИмяРеквизита = Неопределено;
    
    Пока Чтение.Прочитать() Цикл
        Тип = Чтение.ТипТекущегоЗначения;
        Если Тип = ТипЗначенияJSON.НачалоОбъекта И ПоследнееИмяРеквизита<>Неопределено Тогда
            Результат[ПоследнееИмяРеквизита] = ЗаполнитьСтруктуруИзОтветаJSON(Чтение);
        ИначеЕсли Тип = ТипЗначенияJSON.КонецОбъекта Тогда
            Возврат Результат;
            ПоследнееИмяРеквизита = Неопределено;
        ИначеЕсли Тип = ТипЗначенияJSON.ИмяСвойства Тогда
            Результат.Вставить(Чтение.ТекущееЗначение, Неопределено);
            ПоследнееИмяРеквизита = Чтение.ТекущееЗначение;
        ИначеЕсли Тип = ТипЗначенияJSON.Булево или Тип = ТипЗначенияJSON.Строка
            или Тип = ТипЗначенияJSON.Число или Тип = ТипЗначенияJSON.Null Тогда
            Результат[ПоследнееИмяРеквизита] = Чтение.ТекущееЗначение;
        ИначеЕсли Тип = ТипЗначенияJSON.НачалоМассива Тогда
            Результат[ПоследнееИмяРеквизита] = ЗаполнитьМассивИзОтветаJSON(Чтение);
        КонецЕсли;
    КонецЦикла;  
        
    Возврат Результат;
КонецФункции

Функция ЗаполнитьМассивИзОтветаJSON(Знач Чтение)
    
    Результат = Новый Массив;
    
    Пока Чтение.Прочитать() Цикл
        Тип = Чтение.ТипТекущегоЗначения;
        Если Тип = ТипЗначенияJSON.НачалоОбъекта Тогда
            Результат.Добавить(ЗаполнитьСтруктуруИзОтветаJSON(Чтение));
        ИначеЕсли Тип = ТипЗначенияJSON.КонецМассива Тогда
            Возврат Результат;
        КонецЕсли;
    КонецЦикла;  
    
    Возврат Результат;
    
КонецФункции
1 Garykom
 
гуру
10.04.21
20:45
(0) 1. Скрывай портянки под кат и второй тег с /
2. Читай мануалы https://confluence.cdek.ru/pages/viewpage.action?pageId=29923918
2 Garykom
 
гуру
10.04.21
20:46
"Для получения токена необходимо отправить POST-запрос (x-www-form-urlencoded) на URL"
если не дошло
3 VitaliyTokarev
 
10.04.21
20:48
(2) Т.е., вместо    Заголовки.Вставить("Content-Type", "application/javascript");
Я ставлю: Заголовки.Вставить("Content-Type", "x-www-form-urlencoded");
?
4 Garykom
 
гуру
10.04.21
20:49
(2)+ уверен что не дошло поэтому
ошибка в Заголовки.Вставить("Content-Type", "application/javascript");

И в способе передачи параметров
https://developer.mozilla.org/ru/docs/Web/HTTP/Methods/POST

"application/x-www-form-urlencoded: значения кодируются в кортежах с ключом, разделённых символом '&', с '=' между ключом и значением. Не буквенно-цифровые символы - percent encoded: это причина, по которой этот тип не подходит для использования с двоичными данными (вместо этого используйте multipart/form-data)"
5 Garykom
 
гуру
10.04.21
20:51
(3) еще в тело суешь текстом (нужная кодировка учитывая BOM)

grant_type=..&client_id=..&client_secret=..
6 Garykom
 
гуру
10.04.21
20:52
(3) application/x-www-form-urlencoded
7 Garykom
 
гуру
10.04.21
20:54
(5)+ и если кириллица то urlencoded не забыть ))
8 VitaliyTokarev
 
10.04.21
20:54
(6) Ага, спасибо, сейчас потыкаю
9 Garykom
 
гуру
10.04.21
20:56
(8) еще сервисы конфлюэнс/джиры они занудные поэтому
возможно потребется Content-Length: XX
где XX длина тела (5)
10 Garykom
 
гуру
10.04.21
21:07
(0) и да у тебя ИД реальные ? попроси админов удалить
11 VitaliyTokarev
 
10.04.21
21:10
(10) поменяются через 24 часа
2 + 2 = 3.9999999999999999999999999999999...