yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.91k forks source link

RBAC: cache items #3168

Closed evgen-d closed 9 years ago

evgen-d commented 10 years ago

Caching auth items and etc. Discussion - #3166

cebe commented 10 years ago

Another use case for calling checkAccess() multiple times is building a navigation where most of the links need permission check to ensure user is allowed to access the corresponding action. Current implementation I have results in about 100 db queries to build the navigation.

qiangxue commented 10 years ago

Some ideas here:

cebe commented 10 years ago

Looks good to me. Assignment may be stored in web\User as a private property to ensure it only gets loaded once per request.

qiangxue commented 10 years ago

Another solution is to build a NoSQL-backed RBAC manager.

samdark commented 10 years ago

https://github.com/bethrezen/yii2-cached-rbac-dbmanager

evgen-d commented 10 years ago

This extension caches checkAccess result. This is not solution of multiple querying in checkAccessRecursive. And when result is cached rbac may no longer be actual.

mdmunir commented 10 years ago

My proposal for cached rbac dbmanager https://github.com/mdmsoft/yii2-admin/blob/master/components/DbManager.php Each table load only once per request (except assigment when applied to more than one user). After loaded, data saved to memory. Then all process using data from memory. To save memory. Children and assigment, only saved as the name.

$this->_children = [
    'parent_name1' => ['child1', 'child2', 'child3', ...],
    'parent_name2' => ['child1', 'child2', 'child3', ...],
];

$this->_assigments = [
    'userId1' => ['role1', 'role2', 'role3', ...],
];
gimox commented 10 years ago

Usiing rbac, i notice same problem that cebe wrote.... A large number of db query that solwly the app. So for now i rewrote some code to use with an other db. But the best solution for me is use cache components with a nosql db. (Redis or mongo)

RomeroMsk commented 9 years ago

@cebe wrote:

Another use case for calling checkAccess() multiple times is building a navigation where most of the links need permission check to ensure user is allowed to access the corresponding action. Current implementation I have results in about 100 db queries to build the navigation.

What about this case? Why not to cache assignments in memory to avoid duplicated queries in one request? I understand, why we can't use cache engine for this by default, but saving results of SELECT * FROM auth_assignment WHERE user_id='...' in instance is must have: now Yii2 generates this query N times for N Yii::$app->user->can() calls on the page (when building navigation, for example).