Как стать автором
Обновить

Комментарии 26

Самая крутая статья по RBAC, какую я когда-либо видел
Гибкая система, но вот магический bizrul в виде php строки кода, который явно в eval уходит, немного покоробил. Вместо него напрашивается анонимная функция, но я думаю ребята во 2 версии это поправят.
а в чём проблема переопределить метод?

    public function executeBizRule($bizRule, $params, $data)
    {

        if ($bizRule instanceof Closure) {
            return $bizRule($params, $data, $this);
        }
        return parent::executeBizRule($bizRule, $params, $data);
    }
Да, это решает проблему.
Мне тоже не понравилось что только строкой, анонимная функция смотрелась бы куда лучше. И так же пришлось шерстить документацию что бы понять можно ли её туда передать или нет.

Но я подозреваю что разработчики не планировали что люди будут вручную составлять этот файл, предполагается что ты генерируешь его через какой либо ГУИ, а там только строками.
Ну бизнес-правила не всегда такие простые, как в примерах… Там уже гуй не особо поможет, там IDE с автокомплитом и статическим анализом кода нужна, но как выше подсказали, поведение можно переопределить, унаследовавшись от стандартного класса и использовать ананимные функции или даже callable.
Причина, по которой bizrule строка, а не анонимная функция кроется в деталях, отписался ниже
Статья хороша. Мне в своё время пришлось основательно шерстить гугл, чтобы почерпнуть хоть какую нибудь инфу о RBAC.
Вот тут кавычки забыли
'actions'=>array(update),
и тут
array(allow, 'actions'=>array('create'), 'roles'=>array('createNews'), ),
А тут «обернуть» в accessRules
array('allow', 'actions' => array('update'), 'roles' => array( 'updateNews' => array( 'news' => $this->news )), ),
Спасибо, исправил. Просто часть скопировал с IDE с реального проекта, а другую часть дописывал в текстовом редакторе без подсветки, вот и получилась каша.
Господа, существует ли в Yii способ быстро проверять возможность доступа к экшнам контроллера?

Например, при построении меню с помощью CMenu, возникает необходимость отображать конкретный пункт в зависимости от прав пользователя.
Или даже в таком случае выгодно просто использовать проверку доступа к операции?
Спасибо за статью. В свое время тоже столкнулся с проблемой написания веб-интерфейса для управления RBAC. Даже с SamDark тут связывался :) Он мне помог постичь суть дзена.
Но сам так и не дописал более «православную» статью на эту тему.
Стоит добавить, что с точки зрения авторов Yii такой способ использования CAuthManager является не совсем корректным.
В официальной документации:
После создания элементов авторизации, компонент authManager (или его наследники, например, CPhpAuthManager, CDbAuthManager) загружает их автоматически. То есть, приведённый код запускается один раз, а НЕ для каждого запроса.
________________
Once we have established this hierarchy, the authManager component (e.g. CPhpAuthManager, CDbAuthManager) will load the authorization items automatically. Therefore, we only need to run the above code one time, and NOT for every request.

Об этом подробнее рассказано в этой статье www.yiiframework.com/wiki/65
Это же и является причиной, по которой bizRule является строкой(а не к примеру анонимной функцией) и уходит в eval.( Подробнее см. реализацию — CPhpAuthManager.php->save(); и CPhpAuthManager.php->saveToFile();)

Но по моему личному мнению — способ, представленный автором в данной статье, как раз — наиболее удобный. В своих проектах реализовал все аналогично.
Вроде тоже самое что в мануале, но намного понятней. Самая большая проблема официальных мануалов по Yii, это ты их читаешь, все вроде ясно, а потом читаешь снова, потому что, в итоге, не фига не ясно.
Действительно очень хорошая статья по RBAC в yii. Давно уже не видел хороших статей по yii. Добавил в закладки.
Не совсем понял как геттер работает, в accessRules скармливаю в параметры $this->news. А когда $this->news то присваивается. По логике вещей, в accessRules должен быть $this->getNews()
$this->news это виртуальное свойство. При обращении к нему вызовется функция $this->getNews().
Это поведение задается магическим методом __get() класса CComponent, который является прародителем почти для всех классов в Yii.

www.yiiframework.com/wiki/167/understanding-virtual-attributes-and-get-set-methods/
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Вместо геттера я использую переменную для контроллера и пре_фильтр, выполняющий то же самое,
но только прописанный для действий где нужный объект и так будет использоваться, например update, view, но не create.
Ваш вариант здесь получается лучше.

А для того, чтобы обрабатывать сложные бизнес правила я обычно в проекте создаю класс (Access) со статическими методами и константами с названиями действий и ролей, которые и прописываю в checkAccess.
Константы позволяют избежать ошибок при при вызове правила в разных местах;
А использование отдельных функций вместо написания их непосредственно в bizRule убивает двух зайцев: код обрабатывается IDE и не нужно в случае изменения логики править записи в базе (для DbAuth)
  // в контроллере:
 public function accessRules() {
    return array(
      array('allow',
        'actions' => array('create', 'delete', 'update'),
        'roles' => array(Access::EDIT_ARTICLE => array('article' => $this->article)),
      ),
   )


class Access
{
  /** Доступные роли
  ================================ */
  const ROLE_USER = 'user';

  /** Доступные действия для ролей
  ================================ */
  const EDIT_ARTICLE = 'editArticle';

  /** Правила
  ================================ */
  static public $bizRules = array(
    self::EDIT_ARTICLE => 'return Access::editArticle($params["article"]);',
  )

  /** Само сложное правило
  ================================ */
  static public function editArticle($article) {
    return  random(1);  // наша логика
  }
}
статья супер, подскажите новичку, а где эти роли и правила прописывать??? никак не могу понять.
// Иерархию ролей расположим в файле auth.php в директории config приложения
        if ($this->authFile === null) {
            $this->authFile = Yii::getPathOfAlias('application.config.auth') . '.php';
        }
спасибо!
Так же можете в базе данных в соответствующих таблицах (Auth*).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации