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),敬請期待吧。

[考慮目前國內網站大部分採集文章十分頻繁,更有甚者不註明原文出處,原做者更但願看客們查看原文,以防有任何問題不能更新全部文章,避免誤導!]

查看原文

相關文章
相關標籤/搜索