Yii框架授權——accessRules用法
一、訪問控制過濾器(Access Control Filter)
訪問控制過濾器是檢查當前用戶是否能執行訪問的controller action的初步授權模式。這種授權模式基於用戶名,客戶IP地址和訪問類型。訪問控制過濾器適用於簡單的驗證。需要複雜的訪問控制,需要使用將要講解到的基於角色訪問控制(role-based access (RBAC)).
在控制器(controller)裏重載CController::filters方法設置訪問過濾器來控制訪問動作(看 Filter 瞭解更多過濾器設置信息)。
class PostController extends CController
{
......
publicfunction filters()
{
return array(
'accessControl',
);
}
}
在上面,設置的access control過濾器將應用於PostController裏每個動作。過濾器具體的授權規則通過重載控制器的CController::accessRules方法來指定。
class PostController extends CController
{
......
public function accessRules()
{
return array(
array('deny',
'actions'=>array('create', 'edit'),
'users'=>array('?'),
),
array('allow',
'actions'=>array('delete'),
'roles'=>array('admin'),
),
array('deny',
'actions'=>array('delete'),
'users'=>array('*'),
),
);
}
}
上面設定了三個規則,每個用個數組表示。數組的第一個元素不是'allow'就是'deny',其他的是名-值成對形式設置規則參數的。上面的規則這樣理解:create和edit動作不能被匿名執行;delete動作可以被admin角色的用戶執行;delete動作不能被任何人執行。
訪問規則是一個一個按照設定的順序一個一個來執行判斷的。和當前判斷模式(例如:用戶名、角色、客戶端IP、地址)相匹配的第一條規則決定授權的結果。如果這個規則是allow,則動作可執行;如果是deny,不能執行;如果沒有規則匹配,動作可以執行。
爲了確保某類動作在沒允許情況下不被執行,設置一個匹配所有人的deny規則在最後,類似如下:
returnarray(
// ...別的規則...
// 以下匹配所有人規則拒絕'delete'動作
array('deny',
'action'=>'delete',
),
);
因爲如果沒有設置規則匹配動作,動作缺省會被執行。
訪問規則通過如下的上下文參數設置:
actions: 設置哪個動作匹配此規則。
users: 設置哪個用戶匹配此規則。此當前用戶的name被用來匹配. 三種設定字符在這裏可以用:
*: 任何用戶,包括匿名和驗證通過的用戶。
?: 匿名用戶。
@: 驗證通過的用戶。
roles: 設定哪個角色匹配此規則。這裏用到了將在後面描述的role-based access control技術。In particular, the rule is applied if CWebUser::checkAccessreturns true for one of the roles.提示,用戶角色應該被設置成allow規則,因爲角色代表能做某些事情。
ips: 設定哪個客戶端IP匹配此規則。
verbs: 設定哪種請求類型(例如:GET, POST)匹配此規則。
expression: 設定一個PHP表達式。它的值用來表明這條規則是否適用。在表達式,你可以使用一個叫$user的變量,它代表的是Yii::app()->user。
訪問規則中:
expression: 設定一個PHP表達式。它的值用來表明這條規則是否適用。在表達式,你可以使用一個叫$user的變量,它代表的是Yii::app()->user。
expression的具體用法:
class AdminController extends CController
{
public function accessRules()
{
return array(
array('allow', //允許所有人執行'login','error','index'
'actions'=>array('login','error','index'),
'users'=>array('*'),
),
array('allow', //允許超級管理員執行所有動作
'actions'=>array('create','update','delete'),
'expression'=>array($this,'isSuperAdmin'),
),
array('allow',//允許普通管理員執行
'actions'=>array('update'),
'expression'=>array($this,'isNormalAdmin'), //表示調用$this(即AdminController)中的isNormalAdmin方法。
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
protected function isSuperAdmin($user)//判斷是否是超級管理員
{
return ($this->loadModel($user->id)->adminAdminFlag==1);
}
protected function isNormalAdmin($user)//判斷是否是普通管理員
{
return ($this->loadModel($user->id)->adminAdminFlag==0);
}
public function loadModel($id)
{
$model=Admin::model()->findByPk((int)$id);
if($model===null){
throw new CHttpException(404,'頁面不存在');
}
return $model;
}
}
注:其中$user代表Yii::app()->user即登錄用戶。