Как правильно передать параметры в GET-запросе к Rozetka API из 1С, избегая ошибки 'access_denied'?

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

При интеграции информационных систем, таких как 1С, с внешними API (например, Rozetka API), мы часто сталкиваемся с необходимостью отправки HTTP-запросов. Одной из распространенных проблем, приводящих к ошибке "access_denied" или схожим сообщениям об отказе в доступе, является некорректная передача параметров в запросе. Рассмотрим подробно ситуацию, когда пользователь пытается получить описание товара по его идентификатору, используя метод GET, но получает ошибку, в то время как другие запросы работают.

Суть проблемы: Некорректная передача параметров в GET-запросе

Автор столкнулся с ситуацией, когда при отправке GET-запроса на получение описания товара с параметром id в теле запроса, сервер Rozetka API возвращал ошибку "access_denied". В то же время, запросы без параметров, например, для получения списка товаров, успешно выполнялись. Давайте проанализируем код, вызвавший проблему.

Вот фрагмент кода, который изначально использовался для запроса:


Токен = ПолучитьТокенРозеткаНаСервере();
    
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization","Bearer " + Токен);
    
ДанныеТовара = Новый Структура();
ДанныеТовара.Вставить("id", "302179473");
    
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеТовара);
    
ТелоЗапроса = ЗаписьJSON.Закрыть();
    
АдресAPI = "api-seller.rozetka.com.ua";
ssl = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows(), Новый СертификатыУдостоверяющихЦентровWindows());
Соединение = Новый HTTPСоединение(АдресAPI,,,,,60,ssl);
ЗапросHTTP = Новый HTTPЗапрос;
ЗапросHTTP.АдресРесурса = "/items"; // Целевой ресурс для получения информации о товаре
ЗапросHTTP.Заголовки = Заголовки; 
ЗапросHTTP.УстановитьТелоИзСтроки(ТелоЗапроса, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);
    
Ответ = Соединение.ВызватьHTTPМетод("GET", ЗапросHTTP);

В этом коде мы видим, что для HTTP-метода "GET" формируется переменная ТелоЗапроса, которая содержит JSON-объект с идентификатором товара. Затем эта переменная передается в метод ЗапросHTTP.УстановитьТелоИзСтроки(). Именно здесь и кроется основная ошибка.

Разбираемся с HTTP-методами: GET vs. POST

Чтобы понять причину ошибки, давайте вспомним основные принципы работы RESTful API и различия между HTTP-методами, в частности GET и POST.

  1. GET-запросы: Эти запросы предназначены для получения данных с сервера. Они должны быть идемпотентными (многократное выполнение одного и того же запроса не меняет состояние на сервере) и безопасными (не приводят к изменению данных). Важной особенностью GET-запросов является то, что параметры для фильтрации или идентификации ресурса передаются в строке запроса (query string) URL, а не в теле запроса. Тело запроса для GET-методов либо отсутствует, либо игнорируется сервером.
  2. POST-запросы: Эти запросы используются для создания новых ресурсов на сервере. В POST-запросах данные, которые мы отправляем, передаются в теле запроса.

В нашем случае, мы используем метод "GET" для получения информации о товаре по его id. Следовательно, идентификатор товара должен быть частью URL, а не передаваться в теле запроса в формате JSON.

Корректируем запрос к Rozetka API: передача параметров через URL

Исходя из принципов REST, параметр id для GET-запроса к ресурсу /items должен быть передан как параметр URL. Стандартный формат такой передачи — после символа ? в URL, с использованием пары ключ=значение. Если параметров несколько, они разделяются символом &.

Для нашего случая, где мы хотим получить информацию о товаре с id = "302179473", корректный адрес ресурса будет выглядеть так:

/items?id=302179473

Таким образом, нам необходимо изменить способ формирования ЗапросHTTP.АдресРесурса и полностью исключить блок кода, который создает и устанавливает тело запроса для метода GET.

Вот исправленный и рабочий код:


Токен = ПолучитьТокенРозеткаНаСервере();
    
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization","Bearer " + Токен);
    
// Идентификатор товара, который мы хотим получить
ИдентификаторТовара = "302179473"; 
    
АдресAPI = "api-seller.rozetka.com.ua";
// Рекомендуем использовать ЗащищенноеСоединениеOpenSSL с Неопределено,Неопределено
// если не требуются специфические клиентские сертификаты для аутентификации
ssl = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows(), Новый СертификатыУдостоверяющихЦентровWindows()); 
// Альтернативный вариант для более широкой совместимости:
// ssl = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
    
Соединение = Новый HTTPСоединение(АдресAPI,,,,,60,ssl);
    
ЗапросHTTP = Новый HTTPЗапрос;
// Корректная передача параметра 'id' в строке запроса (URL)
ЗапросHTTP.АдресРесурса = "/items?id=" + ИдентификаторТовара; 
ЗапросHTTP.Заголовки = Заголовки; 
    
// Для GET-запросов тело запроса не устанавливается!
// ЗапросHTTP.УстановитьТелоИзСтроки(ТелоЗапроса, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать); - этот блок удаляем
    
Попытка
    Ответ = Соединение.ВызватьHTTPМетод("GET", ЗапросHTTP);
Исключение
    // Обработка исключений, если запрос не удался
    ВызватьИсключение;
КонецПопытки;
    
Если Ответ.КодСостояния = 200 Тогда 
    ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(ТелоОтвета);
    ПолученноеСоответствие = ПрочитатьJSON(Чтение, Истина); 
    // Здесь ПолученноеСоответствие будет содержать описание товара
Иначе
    // Обработка ошибок HTTP (например, 404 Not Found, 401 Unauthorized, 403 Forbidden)
    Ошибка = "Ошибка HTTP: " + Ответ.КодСостояния + ". " + Ответ.ПолучитьТелоКакСтроку();
    Сообщить(Ошибка);
КонецЕсли;

После внесения этих изменений, запрос к Rozetka API будет корректно сформирован, и мы сможем успешно получить описание товара, если все остальные условия (токен, права доступа) выполнены. Автор подтвердил, что это решение помогло устранить ошибку.

Анализируем причины ошибки "access_denied"

Хотя в нашем случае причина "access_denied" была в некорректной передаче параметров, давайте рассмотрим и другие распространенные причины этой или аналогичных ошибок (таких как 401 Unauthorized / 403 Forbidden), которые могут возникнуть при работе с API:

  1. Неверный токен авторизации. Токен мог быть неправильно сформирован, передан или истек. Токены Rozetka являются временными и могут стать неактивными, если не используются более 24 часов (для API Маркетплейса) или 72 часов (для RZ-Delivery API, если постоянно не обновляются). Всегда проверяйте актуальность и правильность передачи токена.
  2. Недостаточные права доступа. Полученный токен может не иметь необходимых прав для выполнения запрашиваемого действия (например, доступа к определенным методам или данным). При создании API-токена в личном кабинете продавца Rozetka можно выбрать роль, к которой будет привязан токен, что определяет его разрешения. Убедитесь, что ваш токен обладает необходимыми разрешениями.
  3. Некорректный формат запроса. Как мы выяснили, это была основная причина проблемы в нашей ситуации. Если запрос сформирован не в соответствии с документацией API (например, параметры передаются не там, где ожидается – в URL, теле запроса или заголовках), сервер может отказать в доступе, даже если токен верен.
  4. Проблемы с SSL-сертификатами. Хотя в нашем случае использовался ЗащищенноеСоединениеOpenSSL, проблемы с SSL/TLS-соединением также могут иногда приводить к ошибкам, блокирующим доступ к API. Убедитесь, что ваше окружение 1С корректно работает с SSL-сертификатами, особенно если вы используете специфические настройки или прокси-серверы. В некоторых случаях может помочь использование ssl = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено) для игнорирования клиентских сертификатов, если они не требуются для аутентификации.

Управление токенами авторизации в 1С

Для авторизации в Rozetka API используется схема Bearer Token. Токен необходимо передавать в заголовке Authorization в формате Bearer <ваш_токен>. В нашем примере это реализовано с помощью:


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

После успешной авторизации вы получаете временный токен, который можно использовать для последующих запросов. Если срок действия токена истек (или вы получили 401 ошибку), его необходимо обновить или получить новый. Важно иметь механизм для проверки срока действия токена и его автоматического обновления в вашей интеграции.

Важность документации API и как с ней работать

Как показывает наш случай, даже при наличии документации API, ее интерпретация может вызвать затруднения. Важно всегда тщательно изучать официальную документацию Rozetka API. Несмотря на то, что иногда примеры могут быть неочевидными или отсутствовать, она содержит подробное описание методов, ожидаемых параметров (их тип, расположение – в URL, теле запроса или заголовках), и возможных ответов, включая коды ошибок. Документация поможет понять, какие методы (GET, POST, PUT, DELETE) используются для конкретных операций и как правильно формировать запросы. Обращайте внимание на разделы "Request Example" или "Parameters" для каждого метода.

Использование объектов 1С для работы с HTTP-запросами

В платформе 1С для работы с HTTP-запросами мы используем ряд стандартных объектов:

Таким образом, для успешной интеграции с Rozetka API необходимо корректно использовать HTTP-методы, передавать параметры в соответствии с требованиями документации (особенно для GET-запросов – через URL), а также правильно управлять токенами авторизации и их правами. Внимательное отношение к деталям и понимание принципов работы RESTful API помогут избежать распространенных ошибок и обеспечат стабильную работу вашей интеграции.

← На главную