仓库源文站点原文


title: "Yii—accessRules 用法" date: 2012-12-12T11:58:00+08:00 categories: draft: false

toc: true

一、访问控制过滤器(Access Control Filter) 访问控制过滤器是检查当前用户是否能执行访问的 controller action 的初步授权模式。这种授权模式基于用户名,客户 IP 地址和访问类型。访问控制过滤器适用于简单的验证。需要复杂的访问控制,需要使用将要讲解到的基于角色访问控制(role-based access (RBAC)). 在控制器(controller)里重载CController::filters方法设置访问过滤器来控制访问动作 (看 Filter 了解更多过滤器设置信息)。

class PostController extends CController
{
......
public function 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',其他的是名 - 值成对形式设置规则参数的。上面的规则这样理解:createedit动作不能被匿名执行;delete动作可以被admin角色的用户执行;delete动作不能被任何人执行。 访问规则是一个一个按照设定的顺序一个一个来执行判断的。和当前判断模式(例如:用户名、角色、客户端 IP、地址)相匹配的第一条规则决定授权的结果。如果这个规则是allow,则动作可执行;如果是deny,不能执行;如果没有规则匹配,动作可以执行。 为了确保某类动作在没允许情况下不被执行,设置一个匹配所有人的deny规则在最后,类似如下:

return array(
 // ... 别的规则...
 // 以下匹配所有人规则拒绝'delete'动作
 array('deny',
 'action'=>'delete',
 ),
 );

因为如果没有设置规则匹配动作,动作缺省会被执行。 访问规则通过如下的上下文参数设置: actions: 设置哪个动作匹配此规则。 users: 设置哪个用户匹配此规则。此当前用户的name 被用来匹配。三种设定字符在这里可以用:

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即登录用户。