Разграничение прав доступа Kohana 3.3

в 16:25, , рубрики: Kohana, Песочница

image
В Кохане встроен модуль авторизации пользователей. В базе уже есть таблица с ролями. Но пошарив по пространствам интернета я так и не нашел как же удобно сделать разграничение прав доступа. Поэтому предлагаю Вам свое решение этой задачи.

Начнем

Все контроллеры я наследую от одного общего 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') — список ролей, которым разрешен доступ.

Интересно узнать Ваше мнение об этом методе решения проблемы.

Автор: alekseyshavrak

Источник

Поделиться

* - обязательные к заполнению поля