Yii2访问控制过滤器accessRules的使用方法

时间: 2017-02-13  分类: Yii2  收藏
yii2访问控制过滤器accessRules使用方法总结

访问控制过滤器是检查当前用户是否能执行访问的controller action的初步授权模式。这种授权模式基于用户名,客户IP地址和访问类型。
访问控制过滤器,适用于简单的验证。需要复杂的访问控制,需要使用基于角色访问控制(role-based access (RBAC))。

打在最前面,如下摘自yiichina里面,估计是yii2普通版本的方式,我没具体研究,如下为高级模板的siteController控制器里的权限控制方式,写法有不同,

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            ’access’ => [
                ’class’ => AccessControl::className(),
                ’rules’ => [
                    [
                        ’actions’ => [’login’,’error’,’captcha’],
                        ’allow’ => true, //直接允许访问,captcha不加在下面的actions里,不然会出现验证码不显示的问题
                    ],
                    [
                        ’actions’ => [’logout’, ’index’],
                        ’allow’ => true,
                        ’roles’ => [’@’], // @ 表示验证通过的用户才有权限 * 任何用户  ? 匿名用户
                    ],
                ],
            ],
            ’verbs’ => [
                ’class’ => VerbFilter::className(),
                ’actions’ => [
                    ’logout’ => [’post’],
                ],
            ],
        ];
    }



以下摘自yiichina
在控制器(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’,其他的是名-值成对形式设置规则参数的。

上面的规则这样理解:

create和edit动作不能被匿名执行;

delete动作可以被admin角色的用户执行;

delete动作不能被任何人执行。

访问规则是一个一个按照设定的顺序一个一个来执行判断的。和当前判断模式(例如:用户名、角色、客户端IP、地址)相匹配的第一条规则决定授权的结果。

如果这个规则是allow,则动作可执行;

如果是deny,不能执行;如果没有规则匹配,动作可以执行。

为了确保某类动作在没允许情况下不被执行,设置一个匹配所有人的deny规则在最后,类似如下:

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


因为如果没有设置规则匹配动作,动作缺省会被执行。

访问规则通过如下的上下文参数设置:

actions: 设置哪个动作匹配此规则。

users: 设置哪个用户匹配此规则。


此当前用户的name 被用来匹配,三种设定字符在这里可以用:

* 任何用户,包括匿名和验证通过的用户。
? 匿名用户。
@ 验证通过的用户。


roles: 设定哪个角色匹配此规则。


这里用到了将在后面描述的role-based access control技术。In particular, the rule is applied if CWebUser::checkAccess returns 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)   //其中$user代表Yii::app()->user即登录用户。
     {
        return ($this->loadModel($user->id)->adminAdminFlag==1);
     }

    //判断是否是普通管理员
     protected function isNormalAdmin($user)    //其中$user代表Yii::app()->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即登录用户。
分享到:

评论

昵 称: