1. 程式人生 > >YII2中使用RBAC對模組,控制器,方法的許可權控制以及規則的使用

YII2中使用RBAC對模組,控制器,方法的許可權控制以及規則的使用

在使用YII2中自帶的RBAC時,需要先配置config/web.php:

return [
    // ...
    'components' => [
        'authManager' => [
            'class' => 'yii\rbac\DbManager',
        ],
        // ...
    ],
];

如果你需要執行yii migrate來建立表,那麼config/console.php也需要同上面一樣配置一下。

cmd進入專案目錄,執行如下命令:

yii migrate [email protected]
/rbac/migrations

你會發現在資料庫中建立了四張表

auth_assignment 角色與使用者的關聯表
auth_item 存放角色與許可權,通過type欄位區分
auth_item_child 存放角色與許可權的上下級關係
auth_rule 規則表,用於擴充套件許可權功能

為了演示,我們在控制器下分別寫四個方法,分別用來建立許可權,建立角色,指派角色,使用規則。

IndexController.php程式碼如下:

<?php

namespace app\controllers;

use YII;
use app\models\MyUserLogin;
use app\rbac\UserUpdSelfRule;
use app\controllers\BaseController;

class IndexController extends BaseController
{

    //首頁
    public function actionIndex()
    {
        $this->renderPartial('index');
    }

    //登陸
    public function actionLogin()
    {
        if (YII::$app->request->isPost) {
            $user = new MyUserLogin();
            $user->load(YII::$app->request->post(), '');

            if ($user->login()) {
                echo '登陸成功';
            } else {
                echo '登陸失敗';
            }

        } else {
            return $this->renderPartial('login');
        }
    }

    //為了演示,這裡我們新增幾條許可權
    public function actionPer()
    {
        $auth = YII::$app->authManager;
        //建立使用者刪除許可權
        $per = $auth->createPermission('user/del');
        $per->description = '刪除使用者';
        $auth->add($per);
        //建立使用者更新許可權
        $per = $auth->createPermission('user/upd');
        $per->description = '更新使用者';
        $auth->add($per);
        //建立使用者新增許可權
        $per = $auth->createPermission('user/add');
        $per->description = '新增使用者';
        $auth->add($per);
        //建立使用者檢視許可權
        $per = $auth->createPermission('user/list');
        $per->description = '檢視使用者列表';
        $auth->add($per);
    }

    //新增角色
    public function actionRole()
    {
        $auth = YII::$app->authManager;

        //新增管理員角色
        $admin = $auth->createRole('admin');
        $admin->description = '管理員';
        $auth->add($admin);
        //給管理員賦予許可權
        $auth->addChild($admin, $auth->getPermission('user/del'));
        $auth->addChild($admin, $auth->getPermission('user/upd'));
        $auth->addChild($admin, $auth->getPermission('user/add'));
        $auth->addChild($admin, $auth->getPermission('user/list'));

        //新增普通員工角色
        $employee = $auth->createRole('employee');
        $employee->description = '普通員工';
        $auth->add($employee);
        $auth->addChild($employee, $auth->getPermission('user/list'));
        $auth->addChild($employee, $auth->getPermission('user/add'));
    }

    //給使用者指派角色
    public function actionAssign()
    {
        $auth = YII::$app->authManager;

        //注意這裡的2是使用者的ID,即你使用者表user裡的ID
        //也可通過YII::$app->user->id獲取
        $auth->assign($auth->getRole('admin'), 1);

        $auth->assign($auth->getRole('employee'), 2);
    }

    //新增規則
    public function actionRule()
    {
        $auth = YII::$app->authManager;
        $rule = new UserUpdSelfRule();
        $auth->add($rule);

        //建立許可權,與規則關聯
        $per = $auth->createPermission('user/upd/updSelf');
        $per->description = '使用者只能修改自已';
        $per->ruleName = $rule->name;
        $auth->add($per);

        //這裡,要注意,要把user/upd/updSelf許可權設為user/upd的父級
        //要不然,普通員工訪問user/upd這個方法會被攔住
        $auth->addChild($per, $auth->getPermission('user/upd'));
        //給普通員工賦予user/upd/updSelf許可權,注意我們這裡並沒有給員工賦予user/upd許可權
        $auth->addChild($auth->getRole('employee'), $per);
    }
}

我們在專案目錄下建立rbac目錄,並建立UserUpdSelfRule.php,來實現使用者只能修改自已資訊的規則。

<?php

//注意名稱空間要跟你的目錄對應
namespace app\rbac;

use yii\rbac\Rule;

//必須繼承自yii\rbac\Rule
class UserUpdSelfRule extends Rule
{
    public $name = 'userUpdSelf';

    //必須要實現execute方法
    //$user表示使用者ID
    //$item規則相關的角色或者許可權
    //$params傳遞過來的引數
    public function execute($user, $item, $params)
    {
        //如果沒有設定引數ID,直接返回true
        if (!isset($params['id'])) {
            return true;
        }
        //判斷id是否是當前使用者ID
        return ($params['id'] == $user) ? true : false;
    }
}

我們訪問index/per檢視資料表中的變化。

訪問index/role結果如下:

訪問index/assign結果如下:

訪問index/rule結果如下:

為了能夠對我們的模組,控制器,方法進行許可權控制,我們需要建立一個基類來統一處理,上面的控制器就是繼承自基類。

BaseController.php程式碼如下:

<?php

namespace app\controllers;

use YII;
use yii\web\Controller;

class BaseController extends Controller
{
    //不需要驗證的
    protected $noCheckAccess = [
        'index/index',
        'index/per',
        'index/role',
        'index/assign',
        'index/rule',
        'index/login',
    ];

    //不需要登陸的
    protected $noLogin = [
        'index/login',
    ];

    //驗證許可權
    //注意,不要把獲取模組名,控制器名,方法名寫到init()函式裡,那樣是獲取不到的
    //這個坑我已經踩了,大家就不用再去踩了
    public function beforeAction($action)
    {
        $mid = !empty($this->module->id) ? $this->module->id : '';
        $cid = !empty($this->id) ? $this->id : '';
        $aid = !empty($action->id) ? $action->id : '';

        //如果模組為basic,我們只驗證控制器/方法
        if ($mid == 'basic') {
            $per = "{$cid}/{$aid}";
        } else {
            $per = "{$mid}/{$cid}/{$aid}";
        }

        if (!in_array($per, $this->noLogin)) {
            if (!$this->checkOnline()) {
                $this->redirect('index/login');
            }
        }

        if (!in_array($per, $this->noCheckAccess)) {
            if (!YII::$app->user->can($per)) {
                die('你沒有許可權');
            }
        }

        return parent::beforeAction($action);
    }

    //檢查是否線上
    public function checkOnline()
    {
        return !empty(YII::$app->user->id) ? true : false;
    }
}

為了演示,我們建立一個UserController.php,程式碼如下:

<?php

namespace app\controllers;

use YII;
use app\controllers\BaseController;

class UserController extends BaseController
{
    public function actionUpd()
    {
        $id = YII::$app->request->get('id', 0);

        echo 'user id : ', YII::$app->user->id, '<br>';

        //先判斷使用者有沒有隻能修改自已的許可權
        if (YII::$app->user->can('user/upd/updSelf')) {
            //然後再判斷修改ID是否與自已的ID一樣,在UserUpdSelfRule裡進行判斷
            if (YII::$app->user->can('user/upd/updSelf', ['id' => $id])) {
                echo '有權修改自已';
            } else {
                echo '不能修改除自已以外的';
            }
        } else {
            echo '修改所有';
        }
    }

    public function actionDel()
    {
        echo 'user id : ', YII::$app->user->id, '<br>';
        echo 'user del';
    }

    public function actionList()
    {
        echo 'user id : ', YII::$app->user->id, '<br>';
        echo 'user list';
    }

    public function actionAdd()
    {
        echo 'user id : ', YII::$app->user->id, '<br>';
        echo 'user add';
    }
}

我的使用者表裡有兩個使用者

分別登陸這兩個使用者,然後讓他們訪問user/add,user/del,user/list,user/upd,結果如下:

admin使用者狀態如下:

test使用者狀態如下:

test之所以能夠訪問user/upd是因為我們把user/upd/updSelf設為了user/upd的父級,如果沒有設定,這裡是會被攔住的。

相關推薦

YII2使用RBAC模組控制器方法許可權控制以及規則的使用

在使用YII2中自帶的RBAC時,需要先配置config/web.php: return [ // ... 'components' => [ 'authManager' => [ 'class' => 'yii\rbac

Python的Numpy模組(1numpy建立)

1.什麼是Numpy?      Numpy   (Numeric Python)      Numpy系統是Python中的一種開源的數值計算擴充套件。        

MyBatis一對映時執行sql語句的寫法

情境再現: 在使用MyBatis來進行多對一對映時,出現了sql語句中某個屬性為空的現象 <!-- 增加 地址資訊--> <insert id="insertAddress" par

前端框架Vue(13)——vue 如何公共css、 js 方法進行單檔案統一管理全域性呼叫

1、前言 最近,為公司開發交付的一個後臺管理系統專案,我使用了 Vue 框架進行開發實踐。 模組化、元件化、工程化的開發體驗非常好。良好的 api,優雅的設計,對於工程師非常友好。 但是由於模組比較多,我對於每個模組分配了不同的

Excel可見資料求和實現完美自動篩選.

在使用EXCEL篩選功能時,有個讓人非常苦惱的事情,就是篩選出來的資料沒有小計,如果用常規的sum函式求和,那些被隱藏的行也被被計算進去,得到的不是小計,而是所有資料的總計。 要實現這個效果,其實非常簡單,下面就跟著我一步一步來吧: 一、自動篩選 (1)先在第19行上面插入

Java各種日期的操作加日期減日期

 Date d=new Date();     SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");     System.out.prin

YII2自定義使用者認證模型完成登陸和註冊

有些時候我們需要自已定義使用者類,操作自已建的使用者表,來完成登陸和註冊功能。 使用者表結構如下,當然可以根據自已的需要新增或刪除: CREATE TABLE `tb_user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '使

YII2使用with關聯查詢時附帶關聯查詢條件

前言:YII2中可以使用model中的relation關係進行表關聯 應用場景舉例: 需要查詢所有使用者的資訊,並關聯查詢(with)出使用者的發表過的文章,且文章的評論不為0的資料。 $user= user::find()->with([

lavarel從零開始-第三彈(路由控制器視圖)

clas space web 傳參 route where ace enter ber routes/web.php寫路由 基本路由: Route::get(‘/‘, function () { return view(‘welcome‘);});Route::get

Thinkphp的RBAC基於角色的許可權控制

可以觀看兄弟連視訊 或者網上下載資料 以下是一些檔案的記錄 RBAC中文權稱,基於角色許可權訪問控制 Role-based Access Control Full擴充套件包。 安全攔截器 認證管理器(識別不同的身份,你的用 戶名和密碼,許可權是否在授權範圍內) 決策訪問管

laravel5.2路由控制器檢視模型

                         laravel5.2路由,控制器,檢視,模型 1  路由(App\Http\routes.php)

es6新增象的特性和方法

script 就是 xxx logs 情況 cti 變量 應用 div 1. 對象簡寫 //曾經假如是這樣的 var name = ‘xxx‘ var obj = { name : name, say : fun

Python象行為與特殊方法(一)象的創建與銷毀

連接 繼承 並不會 參數 asa rac 方式 垃圾收集 shell Python中類調用__new__()類方法來創建實例,調用__init__()方法來初始化對象,對象的銷毀則調用__del__()方法。 __new__()方法第一個參數為類cls,通常返回cls的一個

2.0版本如何取得當前的控制器方法

Nid tro pre var spa pan number 方法 variable 在 控制器 裏面 1 $controllerID = Yii::$app->controller->id; 2 $actionID = Yii::$app->contr

ASP.NET 如何生成的 HTML 內容流進行控制

在進行 ASP.NET 開發時,有時候需要對頁面輸出的最終 HTML 原始碼進行控制,是頁面的 render 方法中很容易實現這個功能。下面就是一個實現的方法,註釋都在程式碼中。 <%@ Page Language="C#" %> <%@ Import

python3.5的lxml沒有etree模組的問題解決方法

工程需要使用etree模組,於是按照網上教程裝好了lxml包,結果發現包中居然沒有etree模組。又去網上搜了一下,遇到同類問題的人很多,但提出重新安裝lxml包的解決方法似乎不可行,探索了一下,得出以

python3的types模組MethodType繫結方法

python3中運用types模組中的MethodType繫結方法到例項到類是非常常用的,這樣可以節省大量的時間和記憶體,可以避免大量重寫相同的方法!當然了,這也比較容易混淆! class Student(object): pass def se

js物件原型(prototype)的使用方法、替換以及注意事項

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <t

Yii2 yiiwebUser的理解和自建的appmodelsUser(基礎版)frontendmodelsUser的應用原理

end his iat getter authent property 用戶id tails uniq yii\web\User 是一個統稱,為用戶,沒有具體實例,只能管理; 此處以app\models\User為基準; app\models\User 是映射數據表us

如果父類有構造函數並且構造函數有參數而子類沒有因為子類繼承了這個構造函數那麽創建子類象的時候要傳參

bsp class nbsp 參數 int init log ini elf 1 class a(): 2 def __init__(self,aa): 3 self.aa = aa 4 class b(a): 5 def do(self)