yii2项目实战-访问控制过滤器ACF讲解

做者:白狼 出处:http://www.manks.top/document/yii2-filter-control.html 本文版权归做者,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。php

什么是访问控制过滤器?字面上来理解就是访问受权呗,对一些具体的操做设定一些规则进行权限控制。html

固然,这里的【操做】便是指控制器的action了。yii2

前面咱们添加新用户的时候,不知你可有疑问:为何咱们访问主页(site/index)就让咱们登陆,可是咱们在未登陆的时候却能够直接添加用户,访问用户列表呢?app

下面就请咱们今天的主角 AccessControl 登场,噼里啪啦的鼓掌...yii

AccessControl其实也就是 yii\filters\AccessControl, 咱们下面简写为 ACF 做为描述。post

ACF,访问控制过滤器,适用于简单的验证,面对的对象即是控制器的action。对于一些复杂的验证方式,咱们后面会说到 Role Based Access Control (rbac).测试

接下来咱们就上面抛出的问题进行解析。网站

有同窗要质疑了,建立新用户的操做,确定要后台管理才能够进行操做,包括列表页等一系列操做,没登陆确定不能访问啊啊啊。code

不急,下面咱们就看看如何经过ACF去对 user-backend/* 的系列操做进行受权限制!htm

打开backend\controller\SiteController.php 咱们看到这样一段代码

public function behaviors()
{
    return [
        'access' => [
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['login', 'error'],
                    'allow' => true,
                ],
                [
                    'actions' => ['logout', 'index'],
                    'allow' => true,
                    'roles' => ['@'],
                ],
            ],
        ],
        'verbs' => [
            'class' => VerbFilter::className(),
            'actions' => [
                'logout' => ['post'],
            ],
        ],
    ];
}

咱们发现AccessControl是以行为behaviors的方式附加在当前控制器。

行为是啥,咱们在配置一文中就开始纠结行为,行为说白了,他就是一个类,经过某些操做,跟现有的类就好了一个绑定。

既然是绑定,天然就是你(行为类)能够用个人(当前类),我(当前类)也能够用你的(行为类)。具体细节,仍是那句老话,到了该说的时候咱们天然会说,如今说太多岂不是跑题了?

回归正题,咱们看看AccessControl是怎样发挥做用的。

不妨打开yii\filters\AccessControl.php文件,init方法中咱们看到 配置项rules在使用以前,都会被建立为 yii\filters\AccessRule 的对象。

也就是说咱们实际的配置应该是这样的

'rules' => [
    [
        'class' => 'yii\filters\AccessRule',
        'actions' => ['login', 'error'],
        'allow' => true,
    ],
],

经过配置一文,很容易就猜到 这里的actions和allow就是 AccessRule的属性了。

接着咱们看到实际的请求过滤是在beforeAction中进行的!也就是说,在beforeAction中加了一层过滤的条件规则!

如此一来,整个过滤的流程你是否是感受到清晰了好多,可是尚未完,咱们尚未说具体的过滤规则,从init方法中,咱们了解到具体的规则便是 yii\filters\AccessRule 类的属性了。也就是说,规则怎么写,就要看你怎么设定accessRule的属性了!属性怎么设置?打开 yii\filters\AccessRule文件,看每个具体的注解!这里就不说了,由于注解已经写得很是详细了,说多了天然就累赘,很差很差。

那接下来咱们就解决问题,UserBackendController/* 全部的操做应该都设置为登陆以后才能够操做

'access' => [
    'class' => AccessControl::className(),
    'rules' => [
        [
            // 当前rule将会针对这里设置的actions起做用,若是actions不设置,默认就是当前控制器的全部操做
            'actions' => ['index', 'view', 'create', 'update', 'delete', 'signup'],
            // 设置actions的操做是容许访问仍是拒绝访问
            'allow' => true,
            // @ 当前规则针对认证过的用户; ? 全部方可都可访问
            'roles' => ['@'],
        ],
    ],
],

咱们再作几个小练习

一、假设index操做只容许post请求才能够访问

'access' => [
    'class' => AccessControl::className(),
    'rules' => [
        [
            // 当前rule将会针对这里设置的actions起做用,若是actions不设置,默认就是当前控制器的全部操做
            'actions' => ['view', 'create', 'update', 'delete', 'signup'],
            // 设置actions的操做是容许访问仍是拒绝访问
            'allow' => true,
            // @ 当前规则针对认证过的用户; ? 全部方可都可访问
            'roles' => ['@'],
        ],
        [
            'actions' => ['index'],
        'allow' => true,
            // 设置只容许操做的action
            'verbs' => ['POST'],
        ],
    ],
],

咱们新增长的一条规则,设置了AccessRule::verbs属性便可。

注意哦,ACF 自上向下逐一检查规则,直到匹配到一个规则。也就是说若是你这里把verbs的actions index也添加一份到上面的那一条规则,verbs这条规则就至关于废掉了!

二、假设更新操做update只有用户test1能够访问,其余用户不能够访问

咱们如今只有一个用户test1, 为了实现命题,在添加一个新用户test2

'access' => [
    'class' => AccessControl::className(),
    'rules' => [
        [
            // 当前rule将会针对这里设置的actions起做用,若是actions不设置,默认就是当前控制器的全部操做
            'actions' => ['index', 'view', 'create', 'delete', 'signup'],
            // 设置actions的操做是容许访问仍是拒绝访问
            'allow' => true,
            // @ 当前规则针对认证过的用户; ? 全部用户都可访问
            'roles' => ['@'],
        ],
        [
            'actions' => ['update'],
            // 自定义一个规则,返回true表示知足该规则,能够访问,false表示不知足规则,也就不能够访问actions里面的操做啦
            'matchCallback' => function ($rule, $action) {
                return Yii::$app->user->id == 1 ? true : false;
            },
            'allow' => true,
        ],
    ],
],

而后你能够经过test1和test2两个帐号测试,会发现只有test1才能够访问update方法,test2就不容许对其进行访问了。

注:用户test1的userId等于1,用户test2的userId等于2

最后,咱们不只学会了ACF,也对user-backend/* 操做进行了部署。

思考一个问题,若是说咱们的管理平台有100个controller, 每一个controller有10个action, 如何处理这个受权的问题?若是又要限制某些用户(注意哦,某些能够指用户组)对某些操做有权限访问,另一些不容许访问又该如何操做?

有人不怕麻烦:那我就加100个AccessControl, 而后第二个问题就写matchCallback, 这种答案简直就是在做死!

下一章,咱们来简单了解下相对而言更强大一点的权限控制,基于角色的访问控制(rbac),敬请期待吧。

[考虑目前国内网站大部分采集文章十分频繁,更有甚者不注明原文出处,原做者更但愿看客们查看原文,以防有任何问题不能更新全部文章,避免误导!]

查看原文

相关文章
相关标签/搜索