Итак:
Есть пачка роутеров с параметрами. Параметров много, в роутерах задаются дефолтные значения и регулярки для валидации. Казалось бы - в контроллере эти переменные проверять ненадо, ведь если человек дошёл до контроллера, значит все проверки роутера выполнились. И тут (ВНЕЗАПНО!) я вспоминаю про стандартный роутер, без всех этих проверок.
Само собой ничего критичного там нет, да и prepared state дают защиту от SQL inject, но возможность вывести сразу все данные на одной странице (пагинация с изменяемым количеством итемов на странице) тоже может доставить хлопот.
Собственно вопрос: можно ли как то запретить переходить по стандартному роутеру для действий, к которым прописан кастомный роутер?
Доку пролистал вдоль и поперёк. Что нарыл:
1.Можно убить стандартный роутер вообще (ну или заменить на заведомо левый). Но этот вариант заставляет писать роутеры для всех страниц
2.Можно в критичных действиях проверять ($this->getFrontController()->getRouter()->getCurrentRouteName() == 'default' ). Достаточно гибкое решение, но генерирует слишком много повторного кода.
3. Зашить предыдущую проверку в плагин фронт контроллера и сочинить конфиг (для определения критичных действий). Тут уже можно разгуляться, но всё равно это смотрится костылём.
А больше, собственно, вариантов я не нашёл, поэтому представляю реализацию 3го описанного варианта.
Сам плагин
Copy Source | Copy HTML-
- /*
* Плагин убивает стандартный роутер для заданных действий
* позволяет проводить проверку переменных в роутерах (что есть та ещё КОРОВЬЯ СИЛА!!!11)
* @author esemi
*/
- class MyDefaultRouterCrunch extends Zend_Controller_Plugin_Abstract
- {
-
- public function routeShutdown(Zend_Controller_Request_Abstract $request)
- {
- $front = Zend_Controller_Front::getInstance();
-
- //составной хеш, сравнивается с параметрами в конфигах
- $hash = $request->getControllerName() . '_' . $request->getActionName();
-
- //имя роутера
- $name = $front->getRouter()->getCurrentRouteName();
-
- //действия для ограничений
- $hits = $front->getParam('bootstrap')->getOption('defaultRouterCrunch');
-
-
- if( $name == 'default' && in_array($hash, $hits) )
- throw new Exception('Доступ в обход роутера. Если Вы не виноваты - сообщите разработчикам');
-
- }
- }
Пример конфига
Copy Source | Copy HTML- resources.frontController.plugins[] = MyDefaultRouterCrunch
-
- ;действия, для которых критичен переход именно по роутеру (controller_action)
- defaultRouterCrunch[] = "worlds_history"
- defaultRouterCrunch[] = "worlds_alliances"
- defaultRouterCrunch[] = "worlds_players"
- defaultRouterCrunch[] = "alliance_players"
- defaultRouterCrunch[] = "alliance_colony"
- defaultRouterCrunch[] = "player_quick"
ПыСы: посоветовался с симфонистами - мы, говорят, стандартный роутер в жизни не видели, всегда описывали каждый доступный юрл. Может и верная практика.
Комментариев нет:
Отправить комментарий