
В Кохане встроен модуль авторизации пользователей. В базе уже есть таблица с ролями. Но пошарив по пространствам интернета я так и не нашел как же удобно сделать разграничение прав доступа. Поэтому предлагаю Вам свое решение этой задачи.
Начнем
Все контроллеры я наследую от одного общего Common.php В нем прописываю базовые настройки проекта: подключение css, js, заголовков, контента, загрузка всех конфигов, и т.д. В зависимости что нужно от проекта.
Для начала объявляем все то, что нам пригодится в других контроллерах.
<?php defined('SYSPATH') or die('No direct script access.'); class Controller_Common extends Controller_Template { public $sys_mes, $auth, $session, $user, $class_id; public $user_roles = array(); public $security = array(); public $template = 'v_common'; public $layout = 'v_column_12'; public $css = array('bootstrap.min', 'style'); public $js = array('jquery-2.0.0.min', 'bootstrap.min'); public $configs = array('order_control', 'payment_method'); }
Далее пишем функцию которая срабатывает до загрузки контролера любой страницы. Ниже описаны только те настройки, которые нам понадобятся. Список ролей можно записать в сессию.
Функция которая делает разграничение — _check_permission()
public function before() { parent::before(); # Установка $this->auth = Auth::instance(); $this->session = Session::instance(); $this->class_id = Get_class($this); # Проверка на авторизованность if($this->auth->logged_in()) { # Индификационные данные $this->user = $this->auth->get_user(); # Получаем список ролей пользователя $this->user_roles = Model::factory('User')->user_roles($this->user->id); } # Проверка прав доступа $this->_check_permission(); # Загрузка конфигов foreach($this->configs as $config) { $this->template->set_global($config, Kohana::$config->load($config)->as_array()); } }
Модель для получения списка ролей. Тут все просто понятно.
class Model_User extends Model_Auth_User { public function user_roles($user_id) { $result = array(); $db = DB::select(array('roles.name', 'name')); # SELECT -> ROLES_USERS $db->from('roles_users'); $db->where('roles_users.user_id', '=', $user_id); # SELECT -> ROLES $db->join('roles'); $db->on('roles.id', '=', 'roles_users.role_id'); $roles = $db->execute()->as_array(); foreach($roles as $role) { array_push($result, $role['name']); } }
Сама функция, которая разграничивает доступ. Не зависимо от директории контроллера, она все равно отработает как надо.
private function _check_permission() { $check_permission = FALSE; $config_security = Kohana::$config->load('security')->as_array(); $action = Request::current()->action(); if(isset($config_security[$this->class_id][$action])) { foreach($config_security[$this->class_id][$action] as $users_role) if(in_array($users_role, $this->user_roles) || in_array($users_role, array('public'))) $check_permission = TRUE; } if(isset($config_security[$this->class_id]['all_actions'])) { foreach($config_security[$this->class_id]['all_actions'] as $users_role) if(in_array($users_role, $this->user_roles)) $check_permission = TRUE; } if($check_permission != TRUE) exit('Access deny - 403 '); }
Конфиг лежит здесь application/config/security.php
В нем мы пишем разрешение на доступ к экшену, иначе получай 403.
<?php defined('SYSPATH') or die('No direct script access.'); return array( # Order 'Controller_Orders' => array( 'index' => array('root', 'manager', 'admin'), 'by_organization' => array('root'), 'add' => array('admin', 'manager'), 'edit' => array('admin', 'manager'), # Auth 'Controller_Auth' => array( 'all_actions' => array('login'), 'login' => array('public'), ), # Organization 'Controller_Organization' => array( 'all_actions' => array('root'), ), );
Controller_Orders — название контроллера.
index — экшен который отрабатывает (если нужно открыть доступ для всех то пишем 'all_actions')
array('admin', 'manager') — список ролей, которым разрешен доступ.
Интересно узнать Ваше мнение об этом методе решения проблемы.
