做者:白狼 出處: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),敬請期待吧。
[考慮目前國內網站大部分採集文章十分頻繁,更有甚者不註明原文出處,原做者更但願看客們查看原文,以防有任何問題不能更新全部文章,避免誤導!]