Reputation: 23
I'm following the Definitive Guide to Yii 2.0. In my application I have two roles: the admin, who can do everything and the viewer, who can do some actions that unregistered users can't do. I'm trying to use default roles functionality of Yii 2 RBAC, but it seems doesn't work. The user table in my database has a column named "role": for admin it's value set to 1 and for viewers = 2.
What I did:
/app/rbac/UserGroupRule.php
namespace app\rbac;
use Yii;
use yii\rbac\Rule;
class UserGroupRule extends Rule {
public $name = 'userGroup';
public function execute($user, $item, $params) {
if (!Yii::$app->user->isGuest) {
$group = Yii::$app->user->identity->role;
if ($item->name === 'admin') {
return $group == 1;
} elseif ($item->name === 'viewer') {
return $group == 1 || $group == 2;
}
}
return false;
}
}
$auth = Yii::$app->authManager;
$rule = new \app\rbac\UserGroupRule;
$auth->add($rule);
$author = $auth->createRole('viewer');
$author->ruleName = $rule->name;
$auth->add($viewer);
$admin = $auth->createRole('admin');
$admin->ruleName = $rule->name;
$auth->add($admin);
$auth->addChild($admin, $viewer);
in my controller:
public function behaviors() {
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['admin'],
'rules' => [
[
'allow' => true,
'actions' => ['admin'],
'roles' => ['admin'],
],
],
],
];
}
When I try to access "admin" action, it says Forbidden #403, even when I'm an admin. How to make it work?
Upvotes: 2
Views: 5337
Reputation: 336
I was facing the same issue with op. Finally made it work after tinkering with xdebug for a while.
I feel the official documentation on default roles is missing a couple important points, I will summarize them below with some of my personal experiences. The project structure is based on Yii 2.0 Advanced Project Template
user
table contains id
and group
. Where group
is type int
, 1 for admin
and 2 for author
Code simplified for clarity.
The rule class, where you put the actual rule logic.
yii/console/controller/UserGroupRule.php
namespace app\rbac;
use Yii;
use yii\rbac\Rule;
/**
* Checks if user group matches
*/
class UserGroupRule extends Rule
{
public $name = 'userGroup';
public function execute($user, $item, $params)
{
if (!Yii::$app->user->isGuest) {
$group = Yii::$app->user->identity->group;
if ($item->name === 'admin') {
return $group == 1;
} elseif ($item->name === 'author') {
return $group == 1 || $group == 2;
}
}
return false;
}
}
Now defining the roles..
yii/console/controller/RbacController.php
namespace console\controllers;
use Yii;
use yii\console\Controller;
class RbacController extends Controller
{
public function actionInit()
{
$auth = Yii::$app->authManager;
$rule = new \app\rbac\UserGroupRule;
$auth->add($rule);
$admin = $auth->createRole('admin');
$admin->ruleName = $rule->name;
$auth->add($admin);
// define 'author' here...
}
}
After you have this file ready, you should be able to run ./yii rbac/init
to generate the rule files:
console/rbac/items.php
console/rbac/rules.php
Important: You need to place the generated files under your desired application folder, this is crucial. Other wise Yii 2.0 will not be able to pick up the rules. For example: yii/backend/rbac/
This is mostly identical to the documentation
yii/commom/config/main.php
Add the following to the return array:
'authManager' => [
'class' => 'yii\rbac\PhpManager',
'defaultRoles' => ['admin', 'author'], // your define roles
],
Now the fun part, under the controller class you would like to apply the rules
yii/backend/controllers/SiteController.php
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => [], // applies to all actions
'roles' => ['admin'], // your defined roles
],
],
],
Up to this point, the rules should be working. Under your controller class, double check Yii::$app->getAuthManager()
see if it contains your defined roles. If not, it means Yii did not pick up the rules correctly, please check previous steps again.
Upvotes: 3
Reputation: 8400
The user table in my database has a column named "role": for admin it's value set to 1 and for viewers = 2
That's not how it works unfortunately.
The rights/roles a user has are (by default) done via the auth_assignment
-table.
Just add an entry in it:
INSERT INTO `auth_assignment` VALUES ("admin", <user-id>, NOW());
(be sure to change the user ID into whatever user you want to make admin.
That should solve your issue.
Edit (as I misread some of your question):
As per this link you can indeed define default roles, but you have to make sure to also reconfigure your authManager
-component in the configuration file to include the default roles:
'components' => [
'authManager' => [
// ...
'defaultRoles' => ['admin', 'viewer'],
],
],
This list of roles indicate the permissions that always should be checked for every user, no matter if they have an entry in the auth_assignment
-table or not.
Upvotes: 3