Sometimes we may want to avoid too much RBAC, and make our auth system pure role-based.
That is, something like this:
public function behaviors()
{
return [
'access' => [
'class' => 'yii\web\AccessControl',
'rules' => [
[
'allow' => true,
'roles' => ['moderator', 'admin'], // only these roles are allowed to access
],
],
],
];
}
But Yii2 has only two roles by default: ? and @.
Here’s how it can be done.
First, we override AccessRule class:
<?php
namespace app\components;
class AccessRule extends \yii\web\AccessRule
{
protected function matchRole($user)
{
if (empty($this->roles)) {
return true;
}
foreach ($this->roles as $role) {
if ($role === '?' && $user->getIsGuest()) {
return true;
} elseif ($role === '@' && !$user->getIsGuest()) {
return true;
} elseif (!$user->getIsGuest()) {
// user is not guest, let's check his role (or do something else)
if ($role === $user->identity->role) {
return true;
}
}
}
return false;
}
}
Next, we inject this class into access configuration:
public function behaviors()
{
return [
'access' => [
'class' => 'yii\web\AccessControl',
'ruleConfig' => [
'class' => 'app\components\AccessRule' // <==== HERE IT IS!
],
'rules' => [
[
'allow' => true,
'roles' => ['moderator', 'admin'],
],
],
],
];
}
And we’re done here.
(thx Qiang for the tip)