You are viewing revision #11 of this wiki article.
This is the latest version of this article.
You may want to see the changes made in this revision.
How to create a simple (non-RBAC) authorization system
As I notice reading the forum, this is a frequent doubt, so I decided to write this article.
This article covers only the authorization system. I assume you already know how to create an authentication system ( login ).
Database ¶
Firstly, in the 'user' table, create a new integer field called 'accessLevel', that defines the user's access level
Extending CWebUser ¶
in your config file (usually protected/config/main.php)
'components'=>array(
'user'=>array(
//tell the application to use your WebUser class instead of the default CWebUser
'class'=>'WebUser',
//...
),
),
In your components folder ( protected/components ) create a 'WebUser.php' file and a class like this:
/**
* @property boolean $isAdmin
* @property boolean $isSuperAdmin
* @property User $user
*/
class WebUser extends CWebUser{
/**
* cache for the logged in User active record
* @return User
*/
private $_user;
/**
* is the user a superadmin ?
* @return boolean
*/
function getIsSuperAdmin(){
return ( $this->user && $this->user->accessLevel == User::LEVEL_SUPERADMIN );
}
/**
* is the user an administrator ?
* @return boolean
*/
function getIsAdmin(){
return ( $this->user && $this->user->accessLevel >= User::LEVEL_ADMIN );
}
/**
* get the logged user
* @return User|null the user active record or null if user is guest
*/
function getUser(){
if( $this->isGuest )
return null;
if( $this->_user === null ){
$this->_user = User::model()->findByPk( $this->id );
}
return $this->_user;
}
}
Usage ¶
now to validate the user using the filter accessControl
//in your controller
function accessRules(){
return array(
//only accessable by admins
array('allow',
'expression'=>'$user->isAdmin',
//the 'user' var in an accessRule expression is a reference to Yii::app()->user
),
//deny all other users
array('deny',
'users'=>array('*').
),
);
}
using it in your views
if(Yii::app()->user->isAdmin){
echo 'Welcome, administrator!';
}
if(Yii::app()->user->isSuperAdmin){
echo 'You are the man!';
}
Data representation ¶
Now in your User model, to facilitate the data representation of an integer field do the following
class User extends CActiveRecord{
//define the number of levels that you need
const LEVEL_REGISTERED=0, LEVEL_AUTHOR=1, LEVEL_ADMIN=6, LEVEL_SUPERADMIN=99;
/**
* define the label for each level
* @param int $level the level to get the label or null to return a list of labels
* @return array|string
*/
static function getAccessLevelList( $level = null ){
$levelList=array(
self::LEVEL_REGISTERED => 'Registered',
self::LEVEL_AUTHOR => 'Author',
self::LEVEL_ADMIN => 'Administrator'
);
if( $level === null)
return $levelList;
return $levelList[ $level ];
}
}
//using it in forms
$form->dropDownList($model,'accessLevel',$model->accessLevelList);
//using it in DetailView
$this->widget('zii.widgets.CDetailView',array(
'data'=>$model,
'attributes'=>array(
//...,
array(
'name'=>'accessLevel',
'value'=>$model->accessLevelList[$model->accessLevel],
),
),
));
//using it in GridView
$this->widget('zii.widgets.CGridView',array(
'dataProvider'=>$model->search(),
'columns'=>array(
//...,
array(
'name'=>'accessLevel',
'value'=>'$data->accessLevelList[$data->accessLevel]',
),
),
));
//display the administrator label
echo User::getAccessLevelList( User::LEVEL_ADMIN );
And that is it. I hope that helps you.
Cheers, Gustavo
Read more ¶
- Definitive guide - Authentication and Authorization
- Wiki - Understanding Virtual Attributes and get/set methods
- Wiki - How to add more information to Yii::app()->user
- Wiki - Add information to Yii::app()->user by extending CWebUser
Yii already had built in for authorized
Yii had built in function for authorized here
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.