亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > PHP > 正文

ThinkPHP中RBAC權限帶菜單欄顯示和詳細權限操作

2020-03-22 19:17:08
字體:
來源:轉載
供稿:網友
RBAC是什么,能解決什么難題?

RBAC是Role-Based Access Control的首字母,譯成中文即基于角色的權限訪問控制,說白了也就是用戶通過角色與權限進行關聯[其架構靈感來源于操作系統的GBAC(GROUP-Based Access Control)的權限管理控制]。簡單的來說,一個用戶可以擁有若干角色,每一個角色擁有若干權限。這樣,就構造成“用戶-角色-權限”的授權模型。在這種模型中,用戶與角色之間,角色與權限之間,一般者是多對多的關系。其對應關系如下:

image

在許多的實際應用中,系統不只是需要用戶完成簡單的注冊,還需要對不同級別的用戶對不同資源的訪問具有不同的操作權限。且在企業開發中,權限管理系統也成了重復開發效率最高的一個模塊之一。而在多套系統中,對應的權限管理只能滿足自身系統的管理需要,無論是在數據庫設計、權限訪問和權限管理機制方式上都可能不同,這種不致性也就存在如下的憋端:

? 維護多套系統,重復造輪子,時間沒用在刀刃上
? 用戶管理、組織機制等數據重復維護,數據的完整性、一致性很難得到保障
? 權限系統設計不同,概念理解不同,及相應技術差異,系統之間集成存在問題,單點登錄難度大,也復雜的企業系統帶來困難

RBAC是基于不斷實踐之后,提出的一個比較成熟的訪問控制方案。實踐表明,采用基于RBAC模型的權限管理系統具有以下優勢:由于角色、權限之間的變化比角色、用戶關系之間的變化相對要慢得多,減小了授權管理的復雜性,降低管理開銷;而且能夠靈活地支持應用系統的安全策略,并對應用系統的變化有很大的伸縮性;在操作上,權限分配直觀、容易理解,便于使用;分級權限適合分層的用戶級形式;重用性強。

ThinkPHP中RBAC實現體系

ThinkPHP中RBAC基于Java的Spring的Acegi安全系統作為參考原型,并做了相應的簡化處理,以適應當前的ThinkPHP結構,提供一個多層、可定制的安全體系來為應用開發提供安全控制。安全體系中主要有以下幾部分:

? 安全攔截器

? 認證管理器

? 決策訪問管理器

? 運行身份管理器

安全攔截器

安全攔截器就好比一道道門,在系統的安全防護系統中可能存在很多不同的安全控制環節,一旦某個環節你未通過安全體系認證,那么安全攔截器就會實施攔截。

認證管理器

防護體系的第一道門就是認證管理器,認證管理器負責決定你是誰,一般它通過驗證你的主體(通常是一個用戶名)和你的憑證(通常是一個密碼),或者更多的資料來做到。更簡單的說,認證管理器驗證你的身份是否在安全防護體系授權范圍之內。

訪問決策管理

雖然通過了認證管理器的身份驗證,但是并不代表你可以在系統里面肆意妄為,因為你還需要通過訪問決策管理這道門。訪問決策管理器對用戶進行授權,通過考慮你的身份認證信息和與受保護資源關聯的安全屬性決定是是否可以進入系統的某個模塊,和進行某項操作。例如,安全規則規定只有主管才允許訪問某個模塊,而你并沒有被授予主管權限,那么安全攔截器會攔截你的訪問操作。
決策訪問管理器不能單獨運行,必須首先依賴認證管理器進行身份確認,因此,在加載訪問決策過濾器的時候已經包含了認證管理器和決策訪問管理器。

為了滿足應用的不同需要,ThinkPHP 在進行訪問決策管理的時候采用兩種模式:登錄模式和即時模式。登錄模式,系統在用戶登錄的時候讀取改用戶所具備的授權信息到 Session,下次不再重新獲取授權信息。也就是說即使管理員對該用戶進行了權限修改,用戶也必須在下次登錄后才能生效。即時模式就是為了解決上面的問題,在每次訪問系統的模塊或者操作時候,進行即使驗證該用戶是否具有該模塊和操作的授權,從更高程度上保障了系統的安全。

運行身份管理器

運行身份管理器的用處在大多數應用系統中是有限的,例如某個操作和模塊需要多個身份的安全需求,運行身份管理器可以用另一個身份替換你目前的身份,從而允許你訪問應用系統內部更深處的受保護對象。這一層安全體系目前的 RBAC 中尚未實現。

ThinkPHP中RBAC認證流程

對應上面的安全體系,ThinkPHP 的 RBAC 認證的過程大致如下:

1、判斷當前模塊的當前操作是否需要認證

2、如果需要認證并且尚未登錄,跳到認證網關,如果已經登錄 執行5

3、通過委托認證進行用戶身份認證

4、獲取用戶的決策訪問列表

5、判斷當前用戶是否具有訪問權限

權限管理的具體實現過程

RBAC相關的數據庫介紹

在ThinkPHP完整包,包含了RBAC處理類RBAC.html' target='_blank'>class.php文件,位于Extend/Library/ORG/Util。打開該文件,其中就包含了使用RBAC必備的4張表,SQL語句如下(復制后請替換表前綴):

CREATE TABLE IF NOT EXISTS `think_access` ( `role_id` smallint(6) unsigned NOT NULL, `node_id` smallint(6) unsigned NOT NULL, `level` tinyint(1) NOT NULL, `module` varchar(50) DEFAULT NULL, KEY `groupId` (`role_id`), KEY `nodeId` (`node_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;CREATE TABLE IF NOT EXISTS `think_node` ( `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `title` varchar(50) DEFAULT NULL, `status` tinyint(1) DEFAULT 0 , `remark` varchar(255) DEFAULT NULL, `sort` smallint(6) unsigned DEFAULT NULL, `pid` smallint(6) unsigned NOT NULL, `level` tinyint(1) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `level` (`level`), KEY `pid` (`pid`), KEY `status` (`status`), KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;CREATE TABLE IF NOT EXISTS `think_role` ( `id` smallint(6) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL, `pid` smallint(6) DEFAULT NULL, `status` tinyint(1) unsigned DEFAULT NULL, `remark` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `pid` (`pid`), KEY `status` (`status`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;CREATE TABLE IF NOT EXISTS `think_role_user` ( `role_id` mediumint(9) unsigned DEFAULT NULL, `user_id` char(32) DEFAULT NULL, KEY `group_id` (`role_id`), KEY `user_id` (`user_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;

下面對RBAC相關的數據庫表及字段作一下介紹:

表名字段名字段類型作用ly_useridINT用戶ID(唯一識別號)usernameVARCHAR(16)用戶名passwordVARCHAR(32)密碼emailVARCHAR(100)用戶郵箱create_timeTIMESTAMP創建時間(時間戳)logintimeTIMESTAMP最近一次登錄時間(時間戳)loginipVARCHAR(15)最近登錄的IP地址statusTINYINT(1)啟用狀態:0:表示禁用;1:表示啟用remarkVARCHAR(255)備注信息ly_roleidINT角色IDnameVARCHAR(20)角色名稱pidSMALLINT(6)父角色對應IDstatusTINYINT(1)啟用狀態(同上)remarkVARCHAR(255)備注信息ly_nodeidSMALLINT(6)節點IDnameVARCHAR(20)節點名稱(英文名,對應應用控制器、應用、方法名)titleVARCHAR(50)節點中文名(方便看懂)statusTINYINT(1)啟用狀態(同上)remarkVARCHAR(255)備注信息sortSMALLINT(6)排序值(默認值為50)pidSMALLINT(6)父節點ID(如:方法pid對應相應的控制器)levelTINYINT(1)節點類型:1:表示應用(模塊);2:表示控制器;3:表示方法ly_role_useruser_idINT用戶IDrole_idSMALLINT(6)角色IDly_accessrole_idSMALLINT(6)角色IDnode_idSMALLINT(6)節點IDlevel module

以下是數據庫表各字段的關聯關系:

image

實現RBAC管理的前導性工作

基于ThinkPHP實現RBAC的權限管理系統中,首先要做一些前導性的工作(系統數據庫設計TP已經為我們完成了),主要分以下幾個方面:

? 用戶(增、刪、改、查)
? 角色(增、刪、改、查)
? 節點(增、刪、改、查)
? 配置權限(更新權限)

具體實現的代碼如下(相關解釋均在注釋之中):

 ?phpnamespace Home/Controller;use Home/Controller/BaseController;use Home/Model/AdminUserModel;use Org/Util/Tree;use Think/Page;class RbacController extends BaseController //初始化操作 public function _initialize() if (!IS_AJAX) $this- error( 你訪問的頁面不存在,請稍后再試  public function userIndex() if (IS_POST) { $condition[ username ] = array( like , % . trim(I( keybord )) . %  $model = D( AdminUser  $count = $model- where($condition)- count(); $Page = new Page($count, 3); $Page- setConfig( theme , %FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%  $show = $Page- show(); //select search $list = $model- where($condition)- field( password , true)- relation(true)- limit($Page- firstRow . , . $Page- listRows)- select(); $this- show = $show; $this- list = $list; $this- display( AdminUser/index  } else { $model = D( AdminUser  $count = $model- count(); $Page = new Page($count, 6); $Page- setConfig( header , 共%TOTAL_ROW%條  $Page- setConfig( first , 首頁  $Page- setConfig( last , 共%TOTAL_PAGE%頁  $Page- setConfig( prev , 上一頁  $Page- setConfig( next , 下一頁  $Page- setConfig( link , indexpagenumb  $Page- setConfig( theme , %FIRST% %UP_PAGE% %LINK_PAGE% %DOWN_PAGE% %END%  $show = $Page- show(); //select search $list = $model- field( password , true)- relation(true)- limit($Page- firstRow . , . $Page- listRows)- select(); $this- show = $show; $this- list = $list; $this- display( Rbac/userIndex  * 平臺用戶異步驗證 public function checkUser() $username = trim(I( username  $conditions = array( username = :username  $result = M( AdminUser )- where($conditions)- bind( :username , $username)- find(); //如果不存在,則可以創建,也就是返回的是true if (!$result) { echo true  } else { echo false  exit(); * 創建平臺用戶,這里開啟了服務器驗證 public function createAdminUser() if (IS_POST) { * [實例化User對象] * D方法實例化模型類的時候通常是實例化某個具體的模型類,如果你僅僅是對數據表進行基本的CURD操作的話, * 使用M方法實例化的話,由于不需要加載具體的模型類,所以性能會更高。 $model = D( AdminUser  * 如果創建失敗 表示驗證沒有通過 輸出錯誤提示信息 * $model- create() 會自動調用驗證規則 if (!$model- create()) return $this- error($model- getError()); //$username = $model- username; //$model- add() 插入數據后會自動的摧毀數據 if (!$uid = $model- add()) return $this- success( 注冊失敗 , U( Rbac/userIndex //獲取用戶id // 如果是注冊用戶的話// session( uid , $uid);// session( username , $username); //用戶添加成功后,給用戶角色表添加數據 $role[ role_id ] = I( role_id  $role[ user_id ] = $uid; //添加該管理員操作到操作日志中 $desc = 給ID為:[ . $_POST[ role_id ] . ]的角色,新增用戶:[ . $_POST[ username ] . ],密碼為:[ . $_POST[ password ] . ] . 其他參數 . $_POST; addOperationLog($desc); if (D( AdminRoleUser )- add($role)) { return $this- success( 添加平臺用戶成功 , U( Rbac/userIndex  } else { return $this- error( 添加平臺用戶失敗 , U( Rbac/userIndex  return $this- success( 添加平臺用戶成功 , U( Rbac/userIndex  $this- role_list = M( AdminRole )- select(); $this- display( Rbac/createAdminUser  * 改變用戶角色 * 可以支持不執行SQL而只是返回SQL語句:$User- fetchSql(true)- add($data); public function updateUser() $userId = I( get.id  if (IS_POST) { $data[ user_id ] = I( post.user_id  $data[ role_id ] = I( post.role_id  $model = M( AdminRoleUser  if ($model- where(array( user_id = $data[ user_id ]))- delete() == false) { return $this- error( 用戶角色修改失敗 , U( Rbac/updateUser , array( id = $userId))); if ($model- add($data) == false) { return $this- error( 用戶角色修改失敗 , U( Rbac/updateUser , array( id = $userId))); return $this- success( 用戶角色修改成功 , U( Rbac/userIndex  $this- role_list = M( AdminRole )- select(); $this- user = M( AdminUser )- join( tour_admin_role_user ON tour_admin_role_user.user_id = tour_admin_user.id )- where(array( id = $userId))- field( user_id,username,role_id )- find(); $this- display(); //刪除用戶 public function delUser() $user_id = I( post.id , , int  $user = D( AdminUser  $result = $user- relation(true)- where(array( id = $user_id))- delete(); if ($result) { //添加該管理員操作到操作日志中 $desc = 刪除用戶ID: . $user_id . 成功  addOperationLog($desc); $response = [ status = 200, errmsg = 刪除成功 , dataList = $result]; return $this- ajaxReturn($response, JSON  //添加該管理員操作到操作日志中 $desc = 刪除用戶ID: . $user_id . 失敗  addOperationLog($desc); $response = [ status = 500, errmsg = 刪除失敗 , dataList = $result]; return $this- ajaxReturn($response, JSON  //設置用戶狀態 public function userStatus() $uid = I( post.id  $db = M( AdminUser  $status = $db- where(array( id = $uid))- getField( status  $status = ($status == 1) ? 0 : 1; if ($db- where(array( id = $uid))- setField( status , $status)) { $response = [ status = 200, errmsg = 改變成功 , dataList = $status]; return $this- ajaxReturn($response, JSON  //添加該管理員操作到操作日志中 $desc = 設置用戶狀態: . $uid . 失敗  addOperationLog($desc); $response = [ status = 500, errmsg = 改變失敗 , dataList = $status]; return $this- ajaxReturn($response, JSON  /***********************************節點開始****************************************************/ public function nodeIndex() $db = M( AdminNode  $node = $db- order( id )- select(); $this- nodelist = Tree::create($node); $this- display( Rbac/nodeIndex  //創建權限表單處理 public function createNode() $db = M( AdminNode  //創建權限表單處理 if (IS_POST) { $db- create(); if (!$db- add()) { return $this- error( 權限添加失敗 , U( Rbac/nodeIndex  return $this- success( 權限添加成功 , U( Rbac/nodeIndex  $node = $db- where( level !=3 )- order( sort )- select(); $this- nodelist = Tree::create($node); $this- display(); * 刪除權限 public function delNode() $result = M( AdminNode )- where(array( id = I( post.id , , int )))- delete(); if ($result) { $response = [ status = 200, errmsg = 刪除成功 , dataList = $result]; return $this- ajaxReturn($response, JSON  $response = [ status = 500, errmsg = 刪除失敗 , dataList = $result]; return $this- ajaxReturn($response, JSON  * 設置權限狀態 public function NodeStatus() $id = I( post.id  $db = M( AdminNode  $status = $db- where(array( id = $id))- getField( status  $status = ($status == 1) ? 0 : 1; if ($db- where(array( id = $id))- setField( status , $status)) { $response = [ status = 200, errmsg = 修改成功 , dataList = $status]; return $this- ajaxReturn($response, JSON  $response = [ status = 500, errmsg = 修改失敗 , dataList = $status]; return $this- ajaxReturn($response, JSON  * 該節點是否在菜單欄顯示 public function showMenus() $id = I( post.id  $db = M( AdminNode  $show = $db- where(array( id = $id))- getField( menus  $menus = ($show == 1) ? 0 : 1; $result = $db- where(array( id = $id))- setField( menus , $menus); if ($result) { $response = [ status = 200, errmsg = 修改成功 , dataList = $result]; return $this- ajaxReturn($response, JSON  $response = [ status = 500, errmsg = 修改失敗 , dataList = $result]; return $this- ajaxReturn($response, JSON  /***********************************角色開始****************************************************/ public function roleIndex() $db = M( AdminRole  $this- rolelist = $db- select(); $this- display(); *創建角色 public function createAdminRole() if (IS_POST) { $name = I( post.name , , strip_tags  $remark = I( post.remark , , strip_tags  $pid = I( post.pid , , strip_tags // 用strip_tags過濾$_GET[ title ] if (empty($name)) return $this- error( 角色名稱不能為空  $role = M( AdminRole  $where[ name ] = :name  $roleName = $role- where($where)- bind( :name , $name, /PDO::PARAM_STR)- getField( name  if ($roleName) return $this- error( 角色名稱: . $name . 已經存在 , U( Rbac/roleIndex  $role- name = $name; $role- remark = $remark; $role- pid = $pid; //create方法并不算是連貫操作,因為其返回值可能是布爾值,所以必須要進行嚴格判斷。 if ($role- create()) { // 如果主鍵是自動增長型 成功后返回值就是最新插入的值 $result = $role- field( name,remark,pid )- add(); //如果在add方法之前調用field方法,則表示只允許寫入指定的字段數據,其他非法字段將會被過濾 if (!$result) return $this- error( 角色添加失敗 , U( Rbac/createpartent  return $this- success( 角色添加成功 , U( Rbac/roleIndex  return $this- success( 角色添加成功 , U( Rbac/roleIndex  $this- display(); *添加權限Node位權限表,Access為權限-角色關聯表 public function addNode() $rid = I( rid , , int  if (!is_numeric($rid)) return $this- success( 參數類型錯誤,必須是數字 , U( Rbac/roleIndex  //getFieldById針對某個字段(ID)查詢并返回某個字段(name)的值 $roleModel = M( AdminRole  $roleWhere[ id ] = :id  $role_name = $roleModel- where($roleWhere)- bind( :id , $rid, /PDO::PARAM_INT)- getField( name  if ($role_name == false) return $this- success( 沒有找到該角色 , U( Rbac/roleIndex  //根據角色遍歷所有權限 $access = M( AdminAccess  if (IS_POST) { $actions = I( post.actions  try { $access- startTrans(); $where[ role_id ] = :role_id  $mod1 = $access- where($where)- bind( :role_id , $rid)- delete(); if (!$mod1) $access- rollback(); $data = array(); foreach ($actions as $value) { $tmp = explode( _ , $value); $data[] = array( role_id = $rid, node_id = $tmp[0], level = $tmp[1] if (!($access- addAll($data))) { $access- rollback(); } else { $access- commit(); return $this- success( 權限設置成功 , U( Rbac/addNode , array( rid = $rid))); } catch (/Exception $e) { $access- rollback(); return $this- success( 權限設置異常 , U( Rbac/addNode , array( rid = $rid))); $node = M( AdminNode )- order( id )- select(); $node_list = Tree::create($node); $node_arr = array(); foreach ($node_list as $value) { $conditions[ node_id ] = $value[ id  $conditions[ role_id ] = $rid; $count = $access- where($conditions)- count(); if ($count) { $value[ access ] = 1  } else { $value[ access ] = 0  $node_arr[] = $value; $this- role_name = $role_name; $this- node_list = $node_arr; $this- rid = $rid; $this- display(); *刪除角色以及角色所擁有的權限 public function delRole() $role_id = I( post.role_id , , int  $user = D( AdminRole  $result = $user- relation(true)- where(array( id = $role_id))- delete(); if ($result) { $response = [ status = 200, errmsg = 修改成功 , dataList = $result]; return $this- ajaxReturn($response, JSON  $response = [ status = 500, errmsg = 修改失敗 , dataList = $result]; return $this- ajaxReturn($response, JSON  * 設置角色狀態 public function roleStatus() $rid = I( post.rid  $db = M( AdminRole  $status = $db- where(array( id = $rid))- getField( status  $status = ($status == 1) ? 0 : 1; if ($db- where(array( id = $rid))- setField( status , $status)) { $response = [ status = 200, errmsg = 修改成功 , dataList = $status]; return $this- ajaxReturn($response, JSON  $response = [ status = 500, errmsg = 修改失敗 , dataList = $status]; return $this- ajaxReturn($response, JSON }

ThinkPHP中RBAC類的詳解

在ThinkPHP處理權限管理中,真正的難點并不是在RBAC類的使用上,上面相關的處理(權限配置,節點管理等);所以當完成以上工作,其實RBAC系統已經完成了90%。下面先從ThinkPHP中RBAC的配置說起(詳細請參看對應的注釋內容):

 ?php
USER_AUTH_ON = true, //是否開啟權限驗證(必配) USER_AUTH_TYPE = 1, //驗證方式(1、登錄驗證;2、實時驗證) USER_AUTH_KEY = uid , //用戶認證識別號(必配) ADMIN_AUTH_KEY = superadmin , //超級管理員識別號(必配) USER_AUTH_MODEL = user , //驗證用戶表模型 ly_user USER_AUTH_GATEWAY = /Public/login , //用戶認證失敗,跳轉URL AUTH_PWD_ENCODER = md5 , //默認密碼加密方式 RBAC_SUPERADMIN = admin , //超級管理員名稱
NOT_AUTH_MODULE = Index,Public , //無需認證的控制器 NOT_AUTH_ACTION = index , //無需認證的方法 REQUIRE_AUTH_MODULE = , //默認需要認證的模塊 REQUIRE_AUTH_ACTION = , //默認需要認證的動作 GUEST_AUTH_ON = false, //是否開啟游客授權訪問 GUEST_AUTH_ID = 0, //游客標記 RBAC_ROLE_TABLE = ly_role , //角色表名稱(必配) RBAC_USER_TABLE = ly_role_user , //用戶角色中間表名稱(必配) RBAC_ACCESS_TABLE = ly_access , //權限表名稱(必配) RBAC_NODE_TABLE = ly_node , //節點表名稱(必配));

注意:

? 以上有的配置項并非必須的,但標有“必配”,則必須配置

? 無需認證的權限和方法與需要認證的模塊和動作可以根據需要選擇性配置,還有部分權限相關配置并未列表出

RBAC處理類提供靜態的方法

ThinkPHP的RBAC處理類提供給我們很多相關的靜態方法如下:

方法名接收參數說明返回值說明RBAC::authenticate(map,map,model=

$map:ThinkPHP數據庫處理類的where條件參

數$model:用戶表名,默認取配置文件C( USER_AUTH_MODEL )

array

RBAC::authenticate(array( username = admin , userpwd = I( POST.pwd , , md5 )));

返回值是在用戶表中,以$map為條件where的查閱結果集

0RBAC::saveAccessList($authId=null);$authId:用戶識別號,默認取C( USER_AUTH_KEY 返回一個空值如果驗證方式為登錄驗證,則將權限寫入session中,否則不作任何處理RBAC::getRecordAccessList(authId=null,authId=null,module=

$authId:用戶識別號(可不傳)

$module:當前操作的模塊名稱

Array返回一個包含權限的ID的數組RBAC::checkAccess()無返回true或false檢查當前操作是否需要認證(根據配置中需要認證和不需要評論的模塊或方法得出)RBAC::checkLogin()無true如果當前操作需要認證且用戶沒有登錄,繼續檢測是否開啟游客授權。如果開啟游客授權,則寫入游客權限;否則跳到登錄頁RBAC::AccessDecision($appName=APP_NAME)$appName:選傳,有默認值

true:表示有操作權限

false:無操作權限

AccessDecision(appName=APPNAME)方法,檢測當前項目模塊操作,是否存在于appName=APPNAME)方法,檢測當前項目模塊操作,是否存在于_SESSION[ _ACCESS_LIST ]數組中$_SESSION[ _ACCESS_LIST ][ 當前操作 ][ 當前模塊 ][ 當前操作 ]是否存在。如果存在表示有權限,返回true;否則返回flase。RBAC::getAccessList($authId)$authId:用戶識別號(選傳,程序自動獲?。〢rray通過數據庫查詢取得當前認證號的所有權限列表RBAC::getModuleAccessList(authId,authId,module)$authId:用戶識別號(必)$module:對應的模塊(必)Array返回指定用戶可訪問的節點權限數組

注意:在使用RBAC::AccessDecision()方法時,如果你開啟了項目分組,則必須傳入當前分組,代碼如下:

//權限驗證if(C( USER_AUTH_ON ) !$notAuth) {import( ORG.Util.RBAC //使用了項目分組,則必須引入GROUP_NAMERBAC::AccessDecision(GROUP_NAME) || $this- error( 你沒有對應的權限 }
RBAC處理類的實際應用

在完成用戶登錄,角色創建,節點增刪改查的工作后,就只剩下了RBAC如何在對應程序代碼中應用了。挻簡單的,只用在原來的代碼其他上改動幾個地方即可。

? 用戶登錄時,寫入用戶權限
? 用戶操作時,進行權限驗證

下面是用戶登錄時的實現代碼:

 ?phpnamespace Home/Controller;use Think/Controller;use Org/Util/Rbac;class LoginController extends Controller public function index() $this- display(); * 異步驗證賬號 public function checkUser() $username = I( username  $conditions = array( username = :username  $result = M( User )- where($conditions)- bind( :username , $username)- find(); //如果不存在,則可以創建,也就是返回的是true if (!$result) { echo false  } else { echo true  exit(); * 異步驗證密碼 public function checkPwd() $username = I( post.username  $password = I( post.password  $conditions = array( username = :username  $result = M( User )- where($conditions)- bind( :username , $username)- find(); if (md5($password) != $result[ password ]) { echo false  } else { echo true  exit(); * 檢查登錄 public function checkLogin() if (!IS_POST) $this- error( 非法訪問  // 采用htmlspecialchars方法對$_GET[ name ] 進行過濾,如果不存在則返回空字符串 $username = I( post.username , , htmlspecialchars  // 采用正則表達式進行變量過濾,如果正則匹配不通過的話,則返回默認值。 //I( get.name , , /^[A-Za-z]+$/  $password = md5(I( post.password  $user = D( AdminUser  $where = array( username = $username); $fields = array( id , password , username , status , expire , logintime // 之查找需要的字段 $result = $user- where($where)- field($fields)- find(); if (!$result || $password != $result[ password ]) return $this- error( 賬號或密碼錯誤 ,U( Home/Login/index  if ($result[ status ] == 0) return $this- error( 該用戶被鎖定,暫時不可登錄 ,U( Home/Login/index  // 是否記住我的登錄,設置一個Cookie,寫在客戶端 if (isset($_POST[ remember ])) { $value = $result[ id ] . | . get_client_ip() . | . $result[ username  $value = encrytion($value, 1); @setcookie( remember , $value, C( AUTO_LOGIN_LIFETIME ), /  // 每天登錄增加經驗值 $today = strtotime(date( Y-m-d // 獲取今天0時0分0秒的時間 // 如果上次的登錄時間小于今天的時間,則增加經驗值 $where2 = array( id = $result[ id  if ($result[ logintime ] $today) { $user- where($where2)- setInc( expire , 10); //更新登錄戶登錄信息 $data_arr = array( id = $result[ id ], logintime = time(), loginip = get_client_ip(), if ($user- save($data_arr)) { // 獲取$_SESSION[ user_id ] 如果不存在則默認為0 session( uid , 0); session( username , $result[ username  session( loginAccount , $result[ username  session( loginUserName , $result[ username  session( uid , $result[ id  //RBAC 開始,用戶認證SESSION標記 ,默認為 authId  session(C( USER_AUTH_KEY ), $result[ id  //如果為超級管理員,則無需驗證 if ($_SESSION[ username ] == C( RBAC_SUPERADMIN )) session(C( ADMIN_AUTH_KEY ), true); //用于檢測用戶權限的方法,并保存到Session中,讀取用戶權限 Rbac::saveAccessList($result[ id  //添加操作日志中 $desc = 登陸成功  addOperationLog($desc); return $this- redirect( Index/index  } else { return $this- error( 2222222222222  public function memberInfo() $user_id = session( user_id  $user = D( User  $where = array( user_id = $user_id); $result = $user- where($where)- select(); $this- result = $result; $this- display(); * 獲取apikey_values public function apikey() $secret = 6JNVkTk4jHsgF0e1oOVLwOZDeq83pDXa  $user_id = I( user_id , , int); // $where = array( user_id = %d ,array($user_id)); $user = M( User  // $result = $user- where($where)- find(); $result = $user- where( user_id = %d , array($user_id))- find(); $hash = sha1($result[ user_id ] . $result[ password ] . $secret); $data = array( apikey_value = $hash, apikey_time = time() $where = array( user_id = $user_id); $user- where($where)- save($data); $this- ajaxReturn($hash); public function hash() if (!IS_POST) { $out_data = array( err_msg = request method is error. , is_success = Fail  exit(json_encode($out_data)); $username = I( username  $password = I( password  $where = array( username = $username); $user = M( User  $result = $user- where($where)- find(); if (!$result || $password != $result[ password ]) { $out_data = array( err_msg = Username or password is incorrect. , is_success = Fail  exit(json_encode($out_data)); * HASH生成規則 $secret = 6JNVkTk4jHsgF0e1oOVLwOZDeq83pDXa  $hash = sha1($result[ user_id ] . $result[ password ] . $secret); $where = array( user_id = $result[ user_id  $data[ apikey_value ] = $hash; $data[ apikey_time ] = time(); $user- where($where)- save($data); $out_data = array( is_success = Success , hash = $hash exit(json_encode($out_data)); public function relationTest() echo get_client_ip(); public function error1(){ $this- display(); public function logout() session( username , NULL); session_unset(); session_destroy(); return $this- redirect( Login/index }

接著在控制器目錄創建一個CommonAction.class.php文件,然后改寫所有要權限驗證的類,讓其繼承自CommonAction。代碼如下:

 ?phpnamespace Home/Controller;use Think/Controller;use Org/Util/Rbac;class BaseController extends Controller// /**// * ThikPHP自動運行方法,每一次,都會自動運行這個方法// * 要判斷一個session值是否已經設置,可以使用// session( ?name 相當于:isset($_SESSION[ name // */ public function _initialize(){ /***************************************網站開關****************************************************/ if(!C( WEB_STATE )) exit( 網站維護中  /***********************************沒有登錄時候時需要執行的代碼**************************************/ if(!isset($_SESSION[C( USER_AUTH_KEY )])) return $this- redirect( Login/index  /***************************************自動登錄配置************************************************/ if(isset($_COOKIE[ remember ]) !isset($_SESSION[ uid ])){ // Cookie 解密 $value = encrytion($_COOKIE[ remember  $result = explode( | ,$value); // 判斷IP地址是否一樣 if($result[1] == get_client_ip()){ session( uid ,$result[0]); session( uid ,$result[2]); /***************************************權限認證****************************************************/ $Public = in_array(MODULE_NAME,explode( , ,C( NOT_AUTH_MODULE ))) || in_array(ACTION_NAME,explode( , ,C( NOT_AUTH_ACTION ))); // 如果不在公共模塊之中,同時開啟權限驗證的話,則開始認證過程 if(C( USER_AUTH_ON ) !$Public) if(!Rbac::AccessDecision()) //通過accessDecision獲取權限信息,true:表示有操作權限,false:無操作權限 return $this- error( 你沒有對應的權限 //沒有獲取到權限信息時需要執行的代碼 /***************************************導航欄菜單顯示****************************************************/ * 思路: * 1.取出所有權限節點。 * 2.取出當前登錄用戶擁有的模塊權限(取英文名稱)和操作權限(取ID) * 3.對所有權限進行遍歷,先匹配模塊權限,不存在刪除,存在則匹配操作權限 // 超級管理員登錄 if(session(C( ADMIN_AUTH_KEY ))) $menus = D( AdminNode )- where( level = 2 )- relation(true)- order( sort desc )- select();//取出所有節點 }else{ * [1]取出所有的權限,是通過關聯模型從數據庫中獲取的 $menus = D( AdminNode )- where( level = 2 )- relation(true)- order( sort desc )- select(); $module = //存放擁有的模塊 $node_id = //存放擁有的模塊 * [2]獲取當前用戶的所有權限,這個是從RBAC中獲取的 $access_list = $_SESSION[ _ACCESS_LIST //當前用戶所擁有的權限 foreach ($access_list as $key = $value) { foreach ($value as $key1 = $value1) { $module = $module. , .$key1; //字符串拼接模塊名稱 foreach ($value1 as $key2 = $value2) { $node_id = $node_id. , .$value2; //字符串拼操作id * [3]去除沒有權限的節點,通過所有權限和用戶已經擁有的權限比較 foreach ($menus as $key = $value) { $all_node[] = $value[ name  if(!in_array(strtoupper($value[ name ]), explode( , , $module))){ unset($menus[$key]); //刪除模塊 }else{ //模塊存在,比較里面的操作 foreach ($value[ node ] as $key1 = $value1) { if(!in_array($value1[ id ], explode( , , $node_id))){ unset($menus[$key][ node ][$key1]); // 刪除操作 $this- menus = $menus;}

在ThinkPHP中提供了一個_initialize()方法,是在類初始化就會執行的,也就是只要后面控制器繼承自CommonAction類,就會在作對應操作時,執行_initialize()方法。

以上就是ThinkPHP中RBAC權限帶菜單欄顯示和詳細權限操作的詳細內容,PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
最近2019好看的中文字幕免费| 亚洲综合色激情五月| 欧美成人在线免费| 久久久久久97| 亚洲夜晚福利在线观看| 91免费视频国产| 欧美激情视频在线| 欧美日韩亚洲精品一区二区三区| 欧美日韩精品在线播放| 欧美日韩在线免费观看| 免费97视频在线精品国自产拍| 欧美日韩免费区域视频在线观看| 国产精品96久久久久久又黄又硬| 亚洲视频在线观看免费| 狠狠干狠狠久久| 久久伊人免费视频| 国产主播在线一区| 国产精品欧美日韩| 成人在线一区二区| 中文字幕日韩高清| 精品亚洲va在线va天堂资源站| 97久久久免费福利网址| 国产精品视频免费观看www| 国产欧美精品va在线观看| 国产精品老牛影院在线观看| 欧美性猛交99久久久久99按摩| 亚洲免费视频观看| 欧美日韩国内自拍| 国产极品jizzhd欧美| 久久精品夜夜夜夜夜久久| 伊人久久久久久久久久久久久| 亚洲国产日韩欧美在线图片| 欧美高清videos高潮hd| 精品国产一区二区三区在线观看| 丝袜美腿精品国产二区| 一区二区亚洲欧洲国产日韩| 久久99精品国产99久久6尤物| 国产精品影院在线观看| 亚洲一区二区少妇| 亚洲精品久久久久久久久| 中文字幕日韩欧美| 黄色成人在线播放| 米奇精品一区二区三区在线观看| 色狠狠av一区二区三区香蕉蜜桃| 韩国精品美女www爽爽爽视频| 清纯唯美亚洲激情| 欧美精品情趣视频| 91国内揄拍国内精品对白| 成人中文字幕在线观看| 欧美日韩国产中字| 亚洲国产精品久久精品怡红院| 国产精品18久久久久久首页狼| 一区二区三欧美| 欧美精品在线极品| 精品久久久久久久久久久久久久| 久久免费视频网| 国产在线999| 成人h猎奇视频网站| 国产又爽又黄的激情精品视频| 成人亚洲欧美一区二区三区| 国产欧美在线看| 国产精品久久久久久久久久东京| 91久久国产精品91久久性色| 国产精品99久久久久久人| 欧美日韩黄色大片| 91九色在线视频| 欧美日韩在线视频一区| 日韩在线观看免费全集电视剧网站| 国产免费一区二区三区在线能观看| 亚洲精品国产精品乱码不99按摩| 欧美男插女视频| 2019最新中文字幕| 亚洲黄色有码视频| 国产欧美最新羞羞视频在线观看| 韩国国内大量揄拍精品视频| 久久成人精品电影| 国模极品一区二区三区| 久久激情五月丁香伊人| 国产一区二区丝袜高跟鞋图片| 亚洲精品福利免费在线观看| 日本精品视频在线播放| 日本一区二区不卡| 最新中文字幕亚洲| 成人福利视频网| 久久久久成人精品| 亚洲精品av在线| 91九色综合久久| 中文字幕久热精品在线视频| 欧美性少妇18aaaa视频| 国产精品视频网址| 久久成人综合视频| 亚洲欧美综合区自拍另类| 一区二区成人av| 中文字幕亚洲综合久久| 国产精品一二三视频| 久久成人av网站| 97在线看免费观看视频在线观看| 久久中文字幕在线视频| 一本色道久久综合狠狠躁篇的优点| 91精品国产综合久久香蕉922| 免费不卡欧美自拍视频| 国产91在线播放| 色妞欧美日韩在线| 97国产成人精品视频| 亚洲免费av片| 在线亚洲欧美视频| 国产午夜精品一区理论片飘花| 国产精品电影网| 国产精品美女无圣光视频| 日韩av电影国产| 亚洲成人激情在线观看| 国产日韩精品综合网站| 成人午夜一级二级三级| 欧美日韩国产综合视频在线观看中文| 亚洲精品视频中文字幕| 在线亚洲午夜片av大片| 日韩av网址在线观看| 91夜夜揉人人捏人人添红杏| 亚洲精品国产品国语在线| 亚洲欧洲国产一区| 国产精品人人做人人爽| 久久久久久欧美| 91亚洲精品久久久久久久久久久久| 96精品久久久久中文字幕| 日韩欧亚中文在线| 一区二区三区www| 亚洲第一二三四五区| 亚洲男人的天堂网站| 97精品久久久| 国产精品久久久久久久9999| www.精品av.com| 欧美激情奇米色| 午夜精品视频网站| 亚洲欧美制服丝袜| 久久久久久久久91| 亚洲欧美日韩国产精品| 久色乳综合思思在线视频| 亚洲毛片在线观看.| 国产91在线播放精品91| 国产精品欧美久久久| 日韩大陆毛片av| 色综合视频网站| 日韩一级黄色av| 日韩在线播放一区| 国产精品第二页| 91牛牛免费视频| 欧美电影免费观看高清| 国产欧美日韩综合精品| 欧日韩不卡在线视频| 欧美一级在线亚洲天堂| 欧美电影电视剧在线观看| 日韩av免费在线观看| 亚洲视频网站在线观看| 亚洲欧美国产一区二区三区| 日韩精品免费看| 亚洲最新av在线| 成人av电影天堂| 国产精品夜色7777狼人| 精品亚洲精品福利线在观看| 欧美成人自拍视频| 青青久久aⅴ北条麻妃| 亚洲精品美女久久久| 亚洲视频在线观看免费| 尤物99国产成人精品视频|