Pull to refresh

Comments 18

Способ 2 — прописать beforeAction, чтобы не писать «if !\Yii::$app->user->can» в каждом методе:

Удобнее всего реализовать это в фильтре по аналогии с AccessControl.
Хранение в базе поля group излишне если вот это не критично:

Не использовать назначение роли юзеру по его ID — вместо этого использовать несколько предустановленных ролей (defaultRoles);


Роли можно построить так, чтобы роли верхнего уровня и были по сути группами.
Но ведь в этом случае придется добавлять роль каждому пользователю. Это удобно, если пользователь должен иметь несколько ролей из иерархии ролей, но в случае с определенным первичным набором ролей удобнее хранить единственную роль пользователя в таблице пользователей.
Вы делаете ровно то же, но при помощи поля в базе данных. Прописываете нечто в `group`. Можно в `defaultRoles` оставить `user` с базовым набором прав, а повышение привилегий делать через API RBAC.
Согласен с Александром. Нет ничего страшного в добавлении роли каждому пользователю (помимо использования defaultRoles можно просто добавлять роль guest автоматически при регистрации каждому пользователю).
Александр, а RBAC можно использовать внутри модулей?

Опишу подробнее.
Есть ядро сайта со своим набором RBAC. Пусть там будут какие-то стандартные роли guest, user, admin. При помощи их он видит (например) только главную страницу.

Теперь пишем модуль news.
И внутри него предполагается свои роли (readerNews, writerNews, moderatorNews). Т.е. они должны «налету» через бизнес-правила присвоиться юзеру, если он попал в раздел новостей.
Если есть модуль blog — то там другие роли. Тоже «налету». Они не зависят друг от друга и никогда не пересекаются.
Так вот, можно ли «дополнять» роли? Можно ли их хранить в разных местах (внутри модуля). Или нужно все хранить в одном месте?

Просто судя по коду PhpManager там предполагается хранение только в одном месте.
Хранить в одном месте, но иерархию можно построить так, чтобы она не пересекалась с основной. Например, префиксируя всё именем модуля.
Теперь в контроллере из метода behaviors можно убрать правило access

А зачем его убирать? Попробуйте воспользоваться matchCallback, внутри которого проверять permission. Либо сделайте по одному правилу на каждый action, указывая в roles название соответствующего permission (фишка в том, что yii\filters\AccessRule проверяет roles посредством того же can).
Да, достаточно удобно использовать Rbac в поведениях. Только в выше описанный метод нужно внести поправку:
class UserGroupRule extends Rule
{
    public function execute($user, $item, $params)
    {
        if (!\Yii::$app->user->isGuest) {

        }
        return false;
    }
}

И после использовать в behaviors -> AccessControl:
'roles' => ['admin']

Не боясь что в этот же раздел попадет виртуальный Guest ;)
Внимание!
Перед выполнением этой команды нужно удалить файлы app/rbac/items.php и app/rbac/rules.php чтобы избежать конфликтов слияния

Можно в методе
RbacController::actionInit
после строчки
$authManager = \Yii::$app->authManager;
добавить
$authManager->removeAll(); 
Это удалит все права, тогда никаких конфликтов не возникнет.
Спасибо тебе, добрый человек!
Если я хочу настраивать привилегии юзергруппы через интерфейс, как быть тогда? Идея в том, чтобы через веб интерфейс можно было создавать юзергруппы и для каждой группы через тот же веб-интефейс настраивать привилегии.
Каким образом ограничить доступ к некоторым методам? Допустим, у контроллера CommentsController к actionDelete() доступ дать только администратору?
$deleteComments= $authManager->createPermission('deleteComments');
$authManager->add($deleteComments);
$authManager->addChild($admin, $deleteComments);
А дальше в методе выполнять проверку:
if (!\Yii::$app->user->can('deleteComments')) {
throw new ForbiddenHttpException('Access denied');
}
Или есть более лаконичное/верное решение?
Спасибо! Очень помогло это решение.
Sign up to leave a comment.

Articles