I have started to use rbac implementing operations, tasks and roles.
For each controller-action pair I have an operation (i.e. user_create, user_delete, user_show, user_update).
To only show the buttons and menus people are allowed to use quite a lot of access checking is performed on every request. This results in up to 50 SQL queries per request, which I think is not acceptable.
My solution to this problem is to cache the access rights in the session:
Yii already provides access rights caching within the same request through the CWebUser method ‘checkAccess()’
So I wrote my own user class MyCWebUser extending CWebUser, it only overrides checkAccess().
<?php
<?php
class MyCWebUser extends CWebUser {
public function checkAccess($operation,$params=array(),$allowCaching=true) {
if($allowCaching && !$this->getIsGuest() && isset(Yii::app()->session['access'][$operation])) {
return Yii::app()->session['access'][$operation];
}
$checkAccess = Yii::app()->getAuthManager()->checkAccess($operation,$this->getId(),$params);
if($allowCaching && !$this->getIsGuest()) {
$access = isset(Yii::app()->session['access']) ? Yii::app()->session['access'] : array();
$access[$operation] = $checkAccess;
Yii::app()->session['access'] = $access;
}
return $checkAccess;
}
}
In your config file you also need to set the new user class:
'components'=>array(
...
'user'=>array(
'class'=>'MyCWebUser',
),
...
)
When using accessControl filters in the controller the access rights are now cached in the session. Manually checking for access rights also works just like before: Yii::app()->user->checkAccess(‘operation_name’).
There is one disadvantage though: changes to the operations/tasks/roles structure or assignment of roles do not take effect until the user has logged out and then logged in again. In my project I can live with that.
To solve that problem as well access rights could be stored in the file cache for example using a key that contains the userId. When changing role assignment to a user you would then have to delete the cache entry for that user, when changing the operations/tasks/roles structure you would have to delete the cache entries for all users.
I hope these ideas can help somebody, good luck with rbac!