摘要:在中,權(quán)限與角色相關(guān)聯(lián),用戶通過(guò)成為適當(dāng)角色的成員而得到這些角色的權(quán)限。這就極大地簡(jiǎn)化了權(quán)限的管理。角色可依新的需求和系統(tǒng)的合并而賦予新的權(quán)限,而權(quán)限也可根據(jù)需要而從某角色中回收。角色與角色的關(guān)系可以建立起來(lái)以囊括更廣泛的客觀情況。
之前有個(gè)朋友問(wèn)我yii的rbac怎么做,以前大學(xué)的時(shí)候有接觸過(guò),很長(zhǎng)時(shí)間沒(méi)用了,也忘記了,正好這幾天比較閑,重新捋了下大體思路,希望可以幫到困在yii的rbac上的門外han~~
RBAC~~什么是RBACRBAC~~權(quán)限認(rèn)證流程基于角色的權(quán)限訪問(wèn)控制(Role-Based Access
Control)作為傳統(tǒng)訪問(wèn)控制(自主訪問(wèn),強(qiáng)制訪問(wèn))的有前景的代替受到廣泛的關(guān)注。在RBAC中,權(quán)限與角色相關(guān)聯(lián),用戶通過(guò)成為適當(dāng)角色的成員而得到這些角色的權(quán)限。這就極大地簡(jiǎn)化了權(quán)限的管理。在一個(gè)組織中,角色是為了完成各種工作而創(chuàng)造,用戶則依據(jù)它的責(zé)任和資格來(lái)被指派相應(yīng)的角色,用戶可以很容易地從一個(gè)角色被指派到另一個(gè)角色。角色可依新的需求和系統(tǒng)的合并而賦予新的權(quán)限,而權(quán)限也可根據(jù)需要而從某角色中回收。角色與角色的關(guān)系可以建立起來(lái)以囊括更廣泛的客觀情況。
用戶登錄后認(rèn)證用戶的角色
根據(jù)角色 查詢出該角色擁有的權(quán)限操作列表
訪問(wèn)某一個(gè)權(quán)限(操作)時(shí)判斷該用戶是否擁有訪問(wèn)的能力
yii如何實(shí)現(xiàn)呢??這里我們采用數(shù)據(jù)庫(kù)的方式實(shí)現(xiàn),會(huì)相對(duì)來(lái)說(shuō)比較安全
RBAC~~權(quán)限數(shù)據(jù)生成首先在web/console.php中配置組件
"authManager" => [ "class" => "yii bacDbManager", // auth_item (role permission) // auth_item_child (role->permission) // auth_assignment (user->role) // auth_rule (rule) "itemTable" => "{{%auth_item}}", "itemChildTable" => "{{%auth_item_child}}", "assignmentTable" => "{{%auth_assignment}}", "ruleTable" => "{{%auth_rule}}", ],
接著使用yii腳本,生成數(shù)據(jù)表
./yii migrate --migrationPath=@yii/rbac/migrations/
然后我們需要讀取所有的控制器與方法 存儲(chǔ)到權(quán)限表,方便判斷的時(shí)候 讀取數(shù)據(jù)庫(kù) 進(jìn)而進(jìn)行判斷
public function actionInit() { $trans = Yii::$app->db->beginTransaction(); try { //構(gòu)建控制器目錄 $dir = dirname(dirname(__FILE__)). "/modules/controllers"; //找到控制器目錄下的所有文件 $controllers = glob($dir. "/*"); $permissions = []; foreach ($controllers as $controller) { $content = file_get_contents($controller); //找到Controller即可 preg_match("/class ([a-zA-Z]+)Controller/", $content, $match); $cName = $match[1]; $permissions[] = strtolower($cName. "/*"); //正則匹配文本中的所以action preg_match_all("/public function action([a-zA-Z_]+)/", $content, $matches); foreach ($matches[1] as $aName) { $permissions[] = strtolower($cName. "/". $aName); } } $auth = Yii::$app->authManager; //為什么$auth可以操作到該表 foreach ($permissions as $permission) { //是否存在該權(quán)限 if (!$auth->getPermission($permission)) { $obj = $auth->createPermission($permission); $obj->description = $permission; $auth->add($obj); } } $trans->commit(); echo "import success "; } catch(Exception $e) { $trans->rollback(); echo "import failed "; } }
接著yii下 就可以生成權(quán)限數(shù)據(jù)了
./yii rbac/init
然后,看看數(shù)據(jù)庫(kù)
RBAC~~權(quán)限訪問(wèn)控制過(guò)濾器的使用原理:
權(quán)限的控制實(shí)則就是判斷當(dāng)前的用戶是否擁有對(duì)方法,控制器訪問(wèn)的權(quán)限 在這之前需要使用過(guò)濾器 對(duì)用戶的登錄與未登錄進(jìn)行認(rèn)證過(guò)濾 ,所有的控制器 extends CommonController,在訪問(wèn)子類控制器的時(shí)候,會(huì)自動(dòng)去訪問(wèn)behaviors方法,在子控制器中,通過(guò)重寫父類的屬性指定允許訪問(wèn)的方法,進(jìn)而實(shí)現(xiàn)過(guò)濾的作用。
//子類可以通過(guò)重寫該屬性 實(shí)現(xiàn)認(rèn)證 public $mustlogin = ["createrule", "createrole", "roles", "assignitem"]; //行為過(guò)濾器 public function behaviors() { return [ "access" => [ "class" => yiifiltersAccessControl::className(), "user" => "admin", "only" => $this->actions, "except" => $this->except, "rules" => [ [ "allow" => false, "actions" => empty($this->mustlogin) ? [] : $this->mustlogin, "roles" => ["?"], ], [ "allow" => true, "actions" => empty($this->mustlogin) ? [] : $this->mustlogin, "roles" => ["@"], ], ], ], ]; } //那么如何實(shí)現(xiàn)訪問(wèn) 判斷用戶是否擁有權(quán)限呢??yii提供了beforeAction,在CommonController進(jìn)行判斷 /*權(quán)限訪問(wèn)判斷*/ public function beforeAction($action) { //調(diào)用父類方法 防止被重寫掉 if (!parent::beforeAction($action)) { return false; } //獲取到當(dāng)前的控制器 $controller = $action->controller->id; $actionName = $action->id; if (Yii::$app->admin->can($controller. "/*")) { return true; } if (Yii::$app->admin->can($controller. "/". $actionName)) { return true; } throw new yiiwebUnauthorizedHttpException("對(duì)不起,您沒(méi)有訪問(wèn)". $controller. "/". $actionName. "的權(quán)限"); // return true; } //這樣即可實(shí)現(xiàn)權(quán)限的訪問(wèn)控制
到這里,我們就是實(shí)現(xiàn)了權(quán)限的訪問(wèn)判斷,接下來(lái) 我們還要實(shí)現(xiàn) 不同用戶顯示不同的菜單,如何實(shí)現(xiàn)呢??
原理:
將菜單欄以數(shù)組的形式進(jìn)行存儲(chǔ),通過(guò)循環(huán)數(shù)組,判斷當(dāng)前用戶訪問(wèn)的控制器是否擁有對(duì)應(yīng)的權(quán)限
controller->id; $action = Yii::$app->controller->action->id; //循環(huán)菜單 foreach (Yii::$app->params["adminmenu"] as $menu) { $show = "hidden"; if (Yii::$app->admin->can($menu["module"]. "/*")) { $show = "show"; } else { if (empty($menu["submenu"]) && !Yii::$app->admin->can($menu["url"])) { continue; } else { foreach ($menu["submenu"] as $sub) { //判斷當(dāng)前的用戶是否擁有訪問(wèn)該控制器的權(quán)限 if (Yii::$app->admin->can($menu["module"]. "/". $sub["url"])) { $show = "show"; } } } } ?>
這樣就實(shí)現(xiàn)了不同登錄用戶 不同菜單的展示
RBAC~~創(chuàng)建不同角色原理:
不同角色擁有不同權(quán)限,超級(jí)管理員可以創(chuàng)建用戶,及分配權(quán)限給不同用戶,首先我們得有個(gè)用戶->
/*角色添加*/ public function actionCreaterole() { if (Yii::$app->request->isPost) { //DBmanager對(duì)象 $auth = Yii::$app->authManager; //創(chuàng)建一個(gè)role的對(duì)象 $role = $auth->createRole(null); $post = Yii::$app->request->post(); if (empty($post["name"]) || empty($post["description"])) { throw new Exception("參數(shù)錯(cuò)誤"); } $role->name = $post["name"]; $role->description = $post["description"]; $role->ruleName = empty($post["rule_name"]) ? null : $post["rule_name"]; $role->data = empty($post["data"]) ? null : $post["data"]; if ($auth->add($role)) { Yii::$app->session->setFlash("info", "添加成功"); } } return $this->render("_createitem"); }
原理:
所謂的分配權(quán)限就是將給用戶分配是否可以訪問(wèn)控制器的權(quán)限,確認(rèn)要分配的對(duì)象 實(shí)則是指定表的user_id對(duì)應(yīng)的item_name值
具體如何做呢?? 看這里->
/* 分配權(quán)限 */ public function actionAssignitem($name) { //獲取到角色 $name = htmlspecialchars($name); $auth = Yii::$app->authManager; //獲取到當(dāng)前角色的信息 $parent = $auth->getRole($name); if (Yii::$app->request->isPost) { $post = Yii::$app->request->post(); if (Rbac::addChild($post["children"], $name)) { Yii::$app->session->setFlash("info", "分配成功"); } } $children = Rbac::getChildrenByName($name); //獲取當(dāng)前用戶的 $roles = Rbac::getOptions($auth->getRoles(),$parent); //獲取當(dāng)前用戶擁有的權(quán)限 $permissions = Rbac::getOptions($auth->getPermissions(), $parent); return $this->render("_assignitem", ["parent" => $name, "roles" => $roles, "permissions" => $permissions, "children" => $children]); }RBAC~~規(guī)則指定,更高級(jí)的權(quán)限指定
接下來(lái),不得不談?wù)剅bac的規(guī)則,這又是個(gè)什么東西呢?? 所謂的規(guī)則 其實(shí)就是對(duì)用戶的權(quán)限的額外限制
原理:
通過(guò)定義規(guī)則類,添加用戶的時(shí)候指定規(guī)則名稱 就可以實(shí)現(xiàn)對(duì)用戶的權(quán)限的額外限制,
數(shù)據(jù)表中,data字段就是實(shí)例化的自定義規(guī)則類對(duì)象
比如我們定義這樣一個(gè)自定義規(guī)則類
/*實(shí)現(xiàn)分類只能由添加者刪除*/ class AuthorRule extends Rule { public $name = "isAuthor"; //當(dāng)前的用戶,權(quán)限,額外的參數(shù) public function execute($user, $item, $params) { $action = Yii::$app->controller->action->id; //對(duì)delete方法 進(jìn)行額外限制 if ($action == "delete") { //獲取到當(dāng)前分類是由那個(gè)用戶添加的 不允許其他用戶刪除 $cateid = Yii::$app->request->get("id"); $cate = Category::findOne($cateid); return $cate->adminid == $user; } return true; } }
我們?nèi)绾蝿?chuàng)建這個(gè)規(guī)則到數(shù)據(jù)表中呢??
/*創(chuàng)建規(guī)則*/ public function actionCreaterule() { if (Yii::$app->request->isPost) { $post = Yii::$app->request->post(); if (empty($post["class_name"])) { throw new Exception("參數(shù)錯(cuò)誤"); } //指定當(dāng)前的規(guī)則命名空間 $className = "appmodels". $post["class_name"]; if (!class_exists($className)) { throw new Exception("規(guī)則類不存在"); } $rule = new $className; //使用authManager組件將當(dāng)前的規(guī)則類 保存到數(shù)據(jù)庫(kù) if (Yii::$app->authManager->add($rule)) { Yii::$app->session->setFlash("info", "添加成功"); } } return $this->render("_createrule"); }
這樣再添加用戶的時(shí)候,就可以指定規(guī)則,進(jìn)而實(shí)現(xiàn)對(duì)更加高級(jí)的指定權(quán)限
到這里,基本完成了用戶創(chuàng)建,權(quán)限分配,及規(guī)則指定,希望可以幫到大家~~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/23117.html
摘要:根據(jù)修改,只是方式,這個(gè)相當(dāng)于的版本。適合用于前后端分離項(xiàng)目,方式提供接口,實(shí)現(xiàn)對(duì)接口的權(quán)限控制。 根據(jù)yii2-admin(https://github.com/mdmsoft/yi...)修改,yii2-admin只是web方式,這個(gè)相當(dāng)于yii2-admin的rest版本。適合用于前后端分離項(xiàng)目,rest方式提供接口,實(shí)現(xiàn)對(duì)接口的權(quán)限控制。項(xiàng)目地址:https://github....
摘要:一基本概念角色是權(quán)限的集合例如建貼改貼。特定情況下,一個(gè)角色可能由其他角色或權(quán)限構(gòu)成,而權(quán)限又由其他的權(quán)限構(gòu)成。提供了兩套授權(quán)管理器和。前者使用腳本存放授權(quán)數(shù)據(jù),而后者使用數(shù)據(jù)庫(kù)存放授權(quán)數(shù)據(jù)。該表存放授權(quán)條目的層次關(guān)系。 一:基本概念 角色是 權(quán)限 的集合 (例如:建貼、改貼)。一個(gè)角色 可以指派給一個(gè)或者多個(gè)用戶。要檢查某用戶是否有一個(gè)特定的權(quán)限, 系統(tǒng)會(huì)檢查該包含該權(quán)限的角色是否指...
摘要:利用渲染后臺(tái)模板后臺(tái)的模板我們采用利用插播一曲是一個(gè)完全響應(yīng)管理模板?;诳蚣埽锥ㄖ颇0?。適合多種屏幕分辨率,從小型移動(dòng)設(shè)備到大型臺(tái)式機(jī)。內(nèi)置了多個(gè)頁(yè)面,包括儀表盤郵箱日歷鎖屏登錄及注冊(cè)錯(cuò)誤錯(cuò)誤等頁(yè)面。 作者:白狼 出處:http://www.manks.top/yii2_fra... 本文版權(quán)歸作者,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保...
摘要:一的前期準(zhǔn)備的權(quán)限管理需要知道怎么給用戶分配角色,給角色分配權(quán)限,以權(quán)限來(lái)精細(xì)化需要的操作,判斷是否有權(quán)限來(lái)操作這一步,達(dá)到管理權(quán)限的目的。若沒(méi)有則渲染不顯示數(shù)據(jù)提交更新相應(yīng)的修改或者增加。 一、RBAC的前期準(zhǔn)備 RBAC的權(quán)限管理需要知道怎么給用戶分配角色,給角色分配權(quán)限,以權(quán)限來(lái)精細(xì)化需要的操作,判斷是否有權(quán)限來(lái)操作這一步,達(dá)到管理權(quán)限的目的。 先展示下要達(dá)到的效果 : show...
摘要:是一個(gè)用語(yǔ)言打造的輕量級(jí)開(kāi)源訪問(wèn)控制框架,目前在開(kāi)源。采用了元模型的設(shè)計(jì)思想,支持多種經(jīng)典的訪問(wèn)控制方案,如基于角色的訪問(wèn)控制基于屬性的訪問(wèn)控制等。 PHP-Casbin 是一個(gè)用 PHP 語(yǔ)言打造的輕量級(jí)開(kāi)源訪問(wèn)控制框架( https://github.com/php-casbin... ),目前在 GitHub 開(kāi)源。PHP-Casbin 采用了元模型的設(shè)計(jì)思想,支持多種經(jīng)典的訪問(wèn)...
閱讀 1958·2021-11-22 09:34
閱讀 3209·2019-08-30 15:55
閱讀 772·2019-08-30 15:53
閱讀 2147·2019-08-30 15:52
閱讀 3075·2019-08-29 18:32
閱讀 2101·2019-08-29 17:15
閱讀 2478·2019-08-29 13:14
閱讀 3646·2019-08-28 18:05