摘要:一的前期準備的權限管理需要知道怎么給用戶分配角色,給角色分配權限,以權限來精細化需要的操作,判斷是否有權限來操作這一步,達到管理權限的目的。若沒有則渲染不顯示數據提交更新相應的修改或者增加。
一、RBAC的前期準備
RBAC的權限管理需要知道怎么給用戶分配角色,給角色分配權限,以權限來精細化需要的操作,判斷是否有權限來操作這一步,達到管理權限的目的。 先展示下要達到的效果 :
左邊為三劍客:用戶、角色、權限;
下面為測試頁面
二、RBAC的數據表
用戶表用的是yii2-admin中migration里面的用戶表
create table `user` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `username` varchar(32) NOT NULL, `auth_key` varchar(32) NOT NULL, `password_hash` varchar(256) NOT NULL, `password_reset_token` varchar(256), `email` varchar(256) NOT NULL, `status` integer not null default 1, `created_at` integer not null, `updated_at` integer not null, KEY `email` (`email`) )ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `role` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL DEFAULT "" COMMENT "角色名稱", `status` tinyint(1) NOT NULL DEFAULT "1" COMMENT "狀態 1:有效 0:無效", `updated_time` timestamp NOT NULL DEFAULT "0000-00-00 00:00:00" COMMENT "最后一次更新時間", `created_time` timestamp NOT NULL DEFAULT "0000-00-00 00:00:00" COMMENT "插入時間", PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="角色表"; CREATE TABLE `permission` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `title` varchar(50) NOT NULL DEFAULT "" COMMENT "權限名稱", `urls` varchar(1000) NOT NULL DEFAULT "" COMMENT "json 數組", `status` tinyint(1) NOT NULL DEFAULT "1" COMMENT "狀態 1:有效 0:無效", `updated_time` timestamp NOT NULL DEFAULT "0000-00-00 00:00:00" COMMENT "最后一次更新時間", `created_time` timestamp NOT NULL DEFAULT "0000-00-00 00:00:00" COMMENT "插入時間", PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="權限詳情表"; CREATE TABLE `user_role` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL DEFAULT "0" COMMENT "用戶id", `role_id` int(11) NOT NULL DEFAULT "0" COMMENT "角色ID", `created_time` timestamp NOT NULL DEFAULT "0000-00-00 00:00:00" COMMENT "插入時間", PRIMARY KEY (`id`), KEY `uid` (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="用戶角色表"; CREATE TABLE `role_permisson` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `role_id` int(11) NOT NULL DEFAULT "0" COMMENT "角色id", `permission_id` int(11) NOT NULL DEFAULT "0" COMMENT "權限id", `created_time` timestamp NOT NULL DEFAULT "0000-00-00 00:00:00" COMMENT "插入時間", PRIMARY KEY (`id`), KEY `role_id` (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="角色權限表";
三、視圖渲染部分。
將準備好的頁面放到views層,在models層建立和表相對應的文件
文件結構:
models層:
view層:
四、邏輯部分:
以角色的增加和修改、給角色增加權限為例:
1、RoleController代碼:
where([ "status" => 1 ])->orderBy(["id"=>SORT_DESC])->all(); return $this->render("index",["roles"=>$roles]); } /* *方法講解: *編輯+新增 *1、如果能獲取到角色的id。則從數據庫取出數據來渲染。若沒有則渲染不顯示數據 *2、提交更新相應的修改或者增加。同樣以id來區分 *3、新增方法簡化還可用load()方法 */ public function actionEdit(){ if (Yii::$app->request->isPost){ //這個request方法是封裝的獲取參數的方法在后面的BaseController里面可以找到 $id = $this->request("id",0); $name = $this->request("name",""); $date_now = date("Y-m-d H:i:s"); //驗證參數TODO: $role = Role::find()->where([ "id" => $id ])->one(); if( $role ){//編輯動作 $role = $role; }else{//添加動作 $role = new Role(); $role->status = 1; $role->created_time = $date_now; } $role->name = $name; $role->updated_time = $date_now; $res = $role->save(0); if ($res){ return $this->redirect("/role/index"); } } $id = $this->request("id",0); $role = []; if( $id ){ $role = Role::find()->where([ "id" => $id ])->one(); } return $this->render("edit",[ "role" => $role ]); } /* *最重要的一步:展示權限和該角色已經擁有的權限 */ public function actionSet(){ if (Yii::$app->request->isPost){ //實現保存選中權限的邏輯 $id = $this->request("id",0); $permission_ids = $this->request("permission_ids",[]); //驗證參數TODO: //取出所有已分配給指定角色的權限 $role_permission_list = RolePermission::find()->where([ "role_id" => $id ])->asArray()->all(); $assign_permission_ids = array_column( $role_permission_list,"permission_id" ); /** * 找出刪除的權限 * 假如已有的權限集合是A,界面傳遞過得權限集合是B * 權限集合A當中的某個權限不在權限集合B當中,就應該刪除 * 使用 array_diff() 計算補集 */ $delete_permission_ids = array_diff( $assign_permission_ids,$permission_ids ); if( $delete_permission_ids ){ RolePermission::deleteAll([ "role_id" => $id,"permission_id" => $delete_permission_ids ]); } /** * 找出添加的權限 * 假如已有的權限集合是A,界面傳遞過得權限集合是B * 權限集合B當中的某個權限不在權限集合A當中,就應該添加 * 使用 array_diff() 計算補集 */ $new_permission_ids = array_diff( $permission_ids,$assign_permission_ids ); if( $new_permission_ids ){ foreach( $new_permission_ids as $permission_id ){ $role_permission = new RolePermission(); $role_permission->role_id = $id; $role_permission->permission_id = $permission_id; $role_permission->created_time = date("Y-m-d H:i:s"); $role_permission->save( 0 ); } } return $this->redirect("/role/index"); } $id = $this->request("id",0); //驗證數據TODO: $role = Role::find()->where([ "id" => $id ])->one(); //取出所有的權限 $permissions = Permission::find()->where([ "status" => 1 ])->orderBy( [ "id" => SORT_DESC ])->all(); //取出所有已分配的權限 $role_permission= RolePermission::find()->where([ "role_id" => $id ])->asArray()->all(); $role_permission_ids = array_column( $role_permission,"permission_id" ); return $this->render("set",[ "role" => $role, "permissions" => $permissions, "role_permission_ids" => $role_permission_ids ]); } }
2、由于基礎的增加改查都會編寫。在這里寫set模板渲染
set.php在view中的role目錄,代碼如下:
"> ">
給三劍客增加、修改、刪除的核心代碼已經結束
五、基礎控制器的編寫:
實現辨別是否有權限訪問要訪問的頁面
BaseController
checkLoginStatus(); if ( !$login_status && !in_array( $action->uniqueId,$this->allowAllAction ) ) { $this->redirect( "/site/login" );//返回到登錄頁面 return false; } // * // * 判斷權限的邏輯是 // * 取出當前登錄用戶的所屬角色, // * 在通過角色 取出 所屬 權限關系 // * 在權限表中取出所有的權限鏈接 // * 判斷當前訪問的鏈接 是否在 所擁有的權限列表中 //判斷當前訪問的鏈接 是否在 所擁有的權限列表中 if( !$this->checkPrivilege( $action->getUniqueId() ) ){ $this->redirect( "/test/forbidden"); return false; } return true; } //檢查是否有訪問指定鏈接的權限 public function checkPrivilege( $url ){ //如果是超級管理員 也不需要權限判斷,這里可以根據自己需要更改 if( Yii::$app->user->identity->id == 1 ){ return true; } //有一些頁面是不需要進行權限判斷的 if( in_array( $url,$this->ignore_url ) ){ return true; } return in_array( $url, $this->getRolePrivilege( ) ); } /* * 獲取某用戶的所有權限 * 取出指定用戶的所屬角色, * 在通過角色 取出 所屬 權限關系 * 在權限表中取出所有的權限鏈接 */ public function getRolePrivilege($uid = 0){ if( !$uid){ $uid = Yii::$app->user->identity->id; } if( !$this->privilege_urls ){ $role_ids = UserRole::find()->where([ "uid" => $uid ])->select("role_id")->asArray()->column(); if( $role_ids ){ //在通過角色 取出 所屬 權限關系 $permission_ids = RolePermission::find()->where([ "role_id" => $role_ids ])->select("permission_id")->asArray()->column(); //在權限表中取出所有的權限鏈接 $list = Permission::find()->where([ "id" => $permission_ids ])->all(); $urls = []; if( $list ){ foreach( $list as $_item ){ $tmp_urls = @json_decode( $_item["urls"],true ); $urls[] = $tmp_urls; } $this->privilege_urls = array_merge( $this->privilege_urls,$urls ); } } } return $this->privilege_urls ; } //驗證登錄是否有效,返回 true or false protected function checkLoginStatus(){ if (Yii::$app->user->isGuest){ return false; } return true; } public function request($key, $def = false) { $result = $def; if(isset($key)) { $request = Yii::$app->getRequest(); if($request->isGet) { $result = $request->get($key, $def); }else if($request->isPost) { $result = $request->post($key, $def); } } return $result; } }
整體代碼沒有準備,如有需要可以留言,準備后會將鏈接寫在這里。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/25601.html
摘要:根據修改,只是方式,這個相當于的版本。適合用于前后端分離項目,方式提供接口,實現對接口的權限控制。 根據yii2-admin(https://github.com/mdmsoft/yi...)修改,yii2-admin只是web方式,這個相當于yii2-admin的rest版本。適合用于前后端分離項目,rest方式提供接口,實現對接口的權限控制。項目地址:https://github....
摘要:利用渲染后臺模板后臺的模板我們采用利用插播一曲是一個完全響應管理模板。基于框架,易定制模板。適合多種屏幕分辨率,從小型移動設備到大型臺式機。內置了多個頁面,包括儀表盤郵箱日歷鎖屏登錄及注冊錯誤錯誤等頁面。 作者:白狼 出處:http://www.manks.top/yii2_fra... 本文版權歸作者,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保...
摘要:原文來自上一篇文章講了用戶的注冊,驗證和登錄,這一篇文章按照約定來說說之中的用戶和權限控制。探尋上面的一些列設置和代碼更改,已經實現了一小部分的用戶控制登錄的用戶才能發表。 原文來自: https://jellybool.com/post/programming-with-yii2-user-access-controls 上一篇文章講了用戶的注冊,驗證和登錄,這一篇文章按照...
摘要:一安裝下載安裝二配置這里記得用單引號而不是雙引號在配置文件中用對整個項目規則限制配置完后取消這個這里是允許訪問的三創建數據庫上面的命令會在數據庫創建表和表。相關表或者執行里的語句四地址欄加上訪問即可出現 一、安裝 https://github.com/mdmsoft/yii2-admin 下載安裝: composer require mdmsoft/yii2-admin 2.x-dev...
閱讀 3225·2021-11-08 13:21
閱讀 1202·2021-08-12 13:28
閱讀 1413·2019-08-30 14:23
閱讀 1935·2019-08-30 11:09
閱讀 850·2019-08-29 13:22
閱讀 2694·2019-08-29 13:12
閱讀 2557·2019-08-26 17:04
閱讀 2265·2019-08-26 13:22