Русский
Русский
English
Статистика
Реклама

Ajax, REST API OpenCart

В статье рассмотрим как устроеныajax запросы в OpenCart, в том числе запросы черезapi OpenCart, познакомимся с новым понятиемfront controllerи немного коснемся темыajax REST API.

Клиент

Клиентская часть OpenCart работает с использованиемjquery, а значит можно использовать$.ajaxиз этой библиотеки.Ссылка на документацию. Примеры ajax запросов на клиентской части можно посмотреть вadmin/view/template/sale/order_form.tpl(.twig для OpenCart 3.0).

Сервер

Просматривая все тот же файлadmin/view/template/sale/order_form.tpl(для OpenCart 2.3)можно понять, чтов качестве адреса вызова используется классическая схема роутинга OpenCart. Посмотрим на один из запросов:

$.ajax({    url: 'index.php?route=customer/customer/autocomplete&token=<?php echo $token; ?>&filter_name=' +  encodeURIComponent(request),    ...

Все просто:url - путь до контроллера и, если надо,имя метода этого контроллера.

То есть, нам нужносоздать класс контроллера, затем из файлов представления можновызывать методы этого контроллераajax запросами.

Создадим контроллер нашего нового тестового модуля по путиadmin/controller/extension/module/myajax.php:

class ControllerExtensionModuleMyAjax extends Controller{    public function index()    {        $this->response->addHeader('Content-Type: application/json');        $this->response->setOutput(json_encode(            [                "success" => true,                 "message" => "ok",                 "data" => []            ]        ));    }}

В классе контроллера есть объектresponse, это экземпляр классаResponse, который расположен по путиsystem/library/response.php. Он позволяет управлять ответом сервера. Нас интересуют только 2 метода:

  • addHeader($header)- добавить http заголовок,headerстроковый аргумент

  • setOutput($output)- установить данные для вывода,outputстроковый аргумент

Для формирования ответа на запрос в методе контроллера можно использовать-

$this->response

Так как OpenCart имеет 2режима доступа/контекста(admin, catalog), то передаваемые данные в запросах разные:

  • admin- требует токен вgetпараметре(получить можно из объекта класса контроллера):

    • для OpenCart 2.3token, который берется из$this->session->data['token']

    • для OpenCart 3.0C4C, который берется изC14CC5C

  • catalog- в общем случае не требует токена, но есть нюансы о которых позже

Теперь чтобы осуществитьajax запросдостаточно в файл представления(читай в html)подставить js(код для OpenCart 2.3):

$.ajax({    url: '<?php echo $admin; ?>index.php?route=extesion/module/myajax&token=<?php echo $token; ?>',    type: 'get',    dataType: 'json',    success: function(json) {        alert("success: "+json["success"]+"\n"+"message: "+json["message"]);    },    error: function(xhr, ajaxOptions, thrownError) {        alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);    }});

В этом коде в urladminэто путь указывающий контекст запроса(admin или catalog). Для контекста есть 2 дефайна, определенных вadmin/config:

  • HTTP_SERVERилиHTTP<b style="box-sizing: border-box;">S</b>_SERVER- путь до директорииadmin(проще - админка), где будет осуществлен поиск контроллера для выполнения запроса

  • HTTP_CATALOGилиC6CC15C- корень сайта, однако контроллеры будут браться из директорииC16CC7C

Ajax API

Просматривая файл представленияadmin/view/template/sale/order_form.tpl(OpenCart 2.3), можно увидеть что из админки осуществляются ajax запросы наcatalogконтекст, с использованием особого токена.

Сначала объявляется глобальная переменнаяtoken, затем ajax запрос на адрес/index.php?route=api/login, который отвечает json данными, в которых есть ключtoken:

var token = ''; // Login to the API$.ajax({    url: '<?php echo $catalog; ?>index.php?route=api/login',    type: 'post',    data: 'key=<?php echo $api_key; ?>',    dataType: 'json',    crossDomain: true,    success: function(json) {    //...         if (json['token']) {            token = json['token'];        }    },    error: function(xhr, ajaxOptions, thrownError) {        alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);    }});

Контроллер этого запроса находится вcatalog/controller/api/login.php ControllerApiLogin::index. Он:

  • создает новую сессию

    (catalog/model/account/api.php - ModelAccountApi::addApiSession) и

  • генерирует для нее случайный токен(функцияtokenнаходится вsystem/helper/general.php),

который возвращается в json этого ajax запроса, если доступ по api(api_key)разрешен для текущего пользователя(Админка-Система-API).

Дальше разбирая представлениеadmin/view/template/sale/order_form.tplможно увидеть, что последующиеajax запросы, которые по адресуroute=api/...используют этот самыйtokenдля определения права доступа, таким образом(в каждом api файле, в каждом методе)C25C существует такой кусок кода для определения права осуществлять запрос:

if (!isset($this->session->data['api_id'])) {    $json['error']['warning'] = $this->language->get('error_permission');} else {    ...}

Ajax запросы черезcatalogконтекст можно осуществлять с использованиемtokenдля безопасного доступа

А теперь копнем глубже и выясним, как это происходит внутри движка, ведь можно отправлятьajax запросыи без токена.

Просматривая код файлаindex.phpотправляемся вsystem/startup.php, оттуда следуем вsystem/framework.phpв самый конец и видим такое вот:

// Front Controller$controller = new Front($registry); // Pre Actionsif ($config->has('action_pre_action')) {    foreach ($config->get('action_pre_action') as $value) {        $controller->addPreAction(new Action($value));    }}

Здесь видим новое понятиеfront controller, код которого находится вsystem/engine/front.phpв классеFront.

Ниже следует мое субъективное определение этого понятия :)

Подробных комментариев найти не удалось, но судя по кодуfront controllerэтоглавный/передний контроллер, онзапускает общий контроллерstartup/routerотносительно директорииcontrollerконтекста(admin/controllerилиcatalog/controller), которыйвыполняет первичные контроллеры,указанные в$_['action_pre_action'];в файлеsystem/config/catalog.php.

В коде выше происходит только добавление первичных контроллеров воfront controller, а их исполнение осуществляется кодом ниже, в методеdispatch(внутри метода перед выполнением action указанного в$config->get('action_router')):

// Dispatch$controller->dispatch(new Action($config->get('action_router')), new Action($config->get('action_error')));

Среди первичных контроллеров естьstartup/sessionотносительноcatalog/controller, где вControllerStartupSession::indexнаходится интересующий наскод для авторизации в api через токен. Вкратце:

  • происходит проверка обращения кapi/и наличияgetпараметраtoken

  • удаление старых api сессий

  • выборка актуальной api сессии на основании ip адреса запросившего и его токена

  • старт сессии с id из$_COOKIE["api"]

  • обновление времени модификации сессии, (чтобы она осталась жива, то есть не была устаревшей)

Теперь, когда исполнение кода дойдет до целевого контроллера,$this->session->data['api_id']уже будет инициализировано, если указана актуальная комбинация токена и ip адреса.

Ajax REST API

Данная глава описывает возможный вариант создания и встроенные средства реализации REST API в OpenCart.

Мы рассмотрели реализациюajax запросов OpenCartдляadminиcatalogконтекстов.

Если говорить обadmin, то предполагается более рациональным реализовывать контроллеры именно вadminконтексте. Однако, такое не всегда возможно. Иногда один и тот же код контроллера(возможно речь о методе контроллера)должен использоваться в обработчикеcatalogсобытия(например при изменении заказа), так и отдельно непосредственно при работе с заказом через админку. Чтобы устранить такие случаи можно реализовать контроллеры вcatalogконтексте и организовать для нихбезопасный доступ(о чем говорится в предыдущей главе).

Для реализацииREST API в OpenCartесть все необходимое:

  • объект для работы с ответом сервера в контроллере$this->response, а именно методыaddHeaderиsetOutput

  • безопасная работа с административным доступом черезcatalogC22Cконтекст

  • единая точка входа api черезC24CC10CC25C контекст, в директориюC26CC11CC27C, можно размещать свои файлы контроллеров и при помощи ajax осуществлять к ним запросы

На стороне сервера надосоздать контроллерывcatalog/controller/api/, а на стороне клиентадобавить ajax запросы в нужные файлы представленийс использованием токена, полученного в результате ajax запросаapi/login. Если в этих файлах нет такого ajax запроса, тогда необходимо добавить его, например, взяв изadmin/view/template/sale/order_form.tpl.Теперь чтобы сделать REST API достаточно изучить, что это такое, несколько ссылок:

Автор: Виталий Бутурлин

Источник: habr.com
К списку статей
Опубликовано: 21.01.2021 12:12:35
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Ajax

Php

Javascript

Программирование

Opencart

Restapi

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru