Simple authorization system

You are viewing revision #10 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.

« previous (#9)next (#11) »

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:

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
Links

Chinese Version

14 0
17 followers
Viewed: 45 705 times
Version: Unknown (update)
Category: How-tos
Written by: Gustavo
Last updated by: Gustavo
Created on: Nov 24, 2011
Last updated: 11 years ago
Update Article

Revisions

View all history

Related Articles