Yii2如何使用存取控制过滤器(ACF)

简介

存取控制过滤器(ACF)是一种通过yii\filters\AccessControl类来实现的简单授权方法, 非常适用于仅需要简单的存取控制的应用。当一个用户请求一个action时,ACF会检查yii\filters\AccessControl::rules列表,判断该用户是否允许执行所请求的action。

AccessControl的例子

假设我们有这样一个控制器,

<?php

namespace app\controllers;

class BookController extends \yii\web\Controller
{
    public function actionIndex()
    {
        return $this->render('index');
    }

    public function actionView()
    {
        return $this->render('view');
    }

    public function actionUpdate()
    {
        return $this->render('update');
    }

    public function actionDelete()
    {
        return $this->render('delete');
    }
}

其中有actionIndexactionViewactionUpdateactionDelete四个action。

首先我们希望任何用户都能访问index、view,登录的用户可以访问update、delete,那么我们可以这样重写behaviors()函数

<?php

namespace app\controllers;

use yii\filters\AccessControl;

class BookController extends \yii\web\Controller
{
    public function behaviors()
    {
        return [
            'access'=>[
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'actions' => ['index','view'],
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                    [
                        'actions' => ['update','delete'],
                        'allow' => true,
                        'roles' => ['@'],
                    ]
                ],
            ],
        ];
    }

    public function actionIndex()
    ...

    public function actionView()
    ...

    public function actionUpdate()
    ...

    public function actionDelete()
    ...
}

在函数behaviors()中,

[
    'class' => AccessControl::className(),
    'rules' => [...],
]

创建了类yii\filters\AccessControl的一个实例,yii\filters\AccessControl继承自yii\base\ActionFilter,通过查阅这两个源码,除了可以配置属性rules,还可以配置的有onlyexceptdenyCallbackuser?)。

only

维护了一个actionID数组,指明该AccessControl应当只对其中所列出的actionID方法起作用;如何没有指定该属性,则表示该AccessControl能对所有的actionID起作用。

except

维护了一个actionID数组,指明该AccessControl不应该管理的actionID。

如果一个actionID同时出现在only和except中,这个actionID不受本ActionFilter约束

denyCallback

当任意一个用户访问自己没有权限访问的actionID时,Yii会作出拒绝,这里可以自定义这个拒绝的动作。

缺省情况下:
- 如果该用户是访客,将调用yii\web\User::loginRequired()将用户的浏览器重定向到登录页面。
- 如果该用户是已认证用户,将抛出一个yii\web\ForbiddenHttpException异常。

在此基础上,我们给出一个稍微复杂的例子,

public function behaviors()
{
    return [
        'access'=>[
            'class' => AccessControl::className(),
            'only' => ['index','view','update','delete'],
            'except' => ['update'],
            'denyCallback' => function($rule, $action){
                throw new ForbiddenHttpException("你没有权限访问这个网页");
            },
            'rules' => [
                [
                    'actions' => ['index','view'],
                    'allow' => true,
                    'roles' => ['?'],
                ],
                [
                    'actions' => ['update','delete'],
                    'allow' => true,
                    'roles' => ['@'],
                ]
            ],
        ],
    ];
}

在这个例子中,我们实例化了一个AccessControl类,only指明该对象负责管理index、view、update和delete,except指明该对象忽略update,onlyexcept两者相结合说明该对象负责管理index、view和delete,不负责管理update。我们可以自己验证一下,update这个actionID不需要登录就可以访问,index和view不需要登录就可以访问,delete需要登录才可以访问。denyCallback又表明,当我们使用游客身份访问delete时,将会返回一个403错误,并提示我们的自定义消息“你没有权限访问这个网页”。

AccessRule的例子

再次回到上面提到的简单的例子,

public function behaviors()
{
    return [
        'access'=>[
            'class' => AccessControl::className(),
            'rules' => [
                [
                    'actions' => ['index','view'],
                    'allow' => true,
                    'roles' => ['?'],
                ],
                [
                    'actions' => ['update','delete'],
                    'allow' => true,
                    'roles' => ['@'],
                ]
            ],
        ],
    ];
}

注意到rules是一个数组,通过分析源码,本质上是如下所示的,rules是一个实例化的AccessRule数组。

'rules' => [
    [
        //'class' => 'yii\filters\AccessRule',
        'actions' => ['index','view'],
        'allow' => true,
        'roles' => ['?'],
    ],
    [
        //'class' => 'yii\filters\AccessRule',
        'actions' => ['update','delete'],
        'allow' => true,
        'roles' => ['@'],
    ]
],

yii\filters\AccessRule中可以配置的属性除了action、allow、roles,还有controllers、ips、verbs、matchCallback、denyCallback。

action

维护了一个actionID数组,并且是大小写敏感的。如果没有设置或者设置为空,则表示该规则会应用到所有的actionID上。

allow

  • true:允许访问
  • false:禁止访问

roles

维护了一个角色数组,其中?代表游客,@代表登录的人,此外还可以是RBAC中定义的角色。

controllers

指定该规则用于匹配哪些控制器。 它的值应为控制器ID数组。匹配比较是大小写敏感的。如果该选项为空,或者不使用该选项, 则意味着当前规则适用于所有的操作。(译者注:这个选项一般是在控制器的自定义父类中使用才有意义)

ips

维护了一个IP地址数组,例如

'ips'=>[
    192,168.*,      //*是通配符
    10.12.1.182,
],

verbs

指定该规则用于匹配哪种请求方法(例如GET,POST)。 这里的匹配大小写不敏感。

matchCallback

指定一个PHP回调函数用于 判定该规则是否满足条件。(译者注:此处的回调函数是匿名函数)

denyCallback

指定一个PHP回调函数, 当这个规则不满足条件时该函数会被调用。(译者注:此处的回调函数是匿名函数)

一个稍微负责的例子,

public function behaviors()
{
    return [
        'access'=>[
            'class' => AccessControl::className(),
            'rules' => [
                //任何人都可以访问index页面
                [
                    'actions' => ['index'],
                    'allow' => true,
                    'roles' => ['?'],
                ],
                //指定的IP内的游客们可以访问view页面
                [
                    'actions' => ['view'],
                    'allow' => true,
                    'ips' => [
                        '192.168.*',
                        '10.13.1.182'
                    ],
                    'roles' => ['?'],
                ],
                //登录的用户可以通过POST方式访问update页面
                [
                    'actions' => ['update'],
                    'allow' => true,
                    'verbs' => ['POST'],
                    'roles' => ['@'],
                ],
                //光棍节可以访问dog页面
                [
                    'actions' => ['dog'],
                    'allow' => true,
                    'matchCallback' => function ($rule, $action) {
                        return date('d-m') === '11-11';
                    },
                ],
                //愚人节这一天不可以访问fool页面
                [
                    'actions' => ['fool'],
                    'allow' => true,
                    'matchCallback' => function ($rule, $action) {
                        return date('d-m') === '04-01';
                    },
                ]
            ],
        ],
    ];
}

参考

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值