Simple authorization system

You are viewing revision #9 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 (#8)next (#10) »

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{
 private $_user;
 //is the user a superadmin ?
 function getIsSuperAdmin(){
  return ( $this->user && $this->user->accessLevel == User::LEVEL_SUPERADMIN );
 }
 //is the user an administrator ?
 function getIsAdmin(){
  return ( $this->user && $this->user->accessLevel >= User::LEVEL_ADMIN );
 }
 //get the logged user
 function getUser(){
  if( $this->isGuest )
   return;
  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
 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: 44 800 times
Version: Unknown (update)
Category: How-tos
Written by: Gustavo
Last updated by: Gustavo
Created on: Nov 24, 2011
Last updated: 10 years ago
Update Article

Revisions

View all history

Related Articles