您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關PHP與RBAC設計思路和數據表設計以及源碼是怎樣的,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
權限系統模塊對于互聯網產品是一個非常重要的功能,可以控制不同的角色合理的訪問不同的資源從而達到安全訪問的作用
ACL
RBAC 基于角色的訪問控制
從上圖我們可以看出,ACL是用戶和權限直接關系的,而RBAC則是通過角色間接關聯用戶和權限的。所以我們注意到角色是RBAC系統的一個重要屬性。
RBAC(Role-Based Access Control,基于角色的訪問控制),就是用戶通過角色與權限進行關聯。簡單地說,一個用戶擁有若干角色,每一個角色擁有若干權限。這樣,就構造成“用戶-角色-權限”的授權模型。在這種模型中,用戶與角色之間,角色與權限之間,一般者是多對多的關系。
原因如下:
方便用戶分組
方便權限分配和回收
擴展方便,可以滿足大部分業務需求
這些也就是我們在說權限管理前,應該先知道權限管理要有功能。
圖中有重要的RBAC模型5大屬性,分別是:
1 用戶屬性(張三、李四、王五)
2 角色屬性(銷售經理、銷售、前臺)
3 用戶與角色的關系(張三 是 銷售經理 、李四 王五 是 銷售)
4 權限(添加客戶、編輯客戶、刪除客戶,查看客戶)
5 權限與角色的關系(銷售 擁有 查看客戶的 權 限、銷售經理可以 查看/添加/刪除/編輯客戶的)
用戶管理
用戶列表
添加用戶
編輯用戶
設置用戶角色
角色管理 角色列表
添加角色
編輯角色
設置角色權限
權限管理
權限列表
新增權限
編輯權限
如圖所示
用戶表
CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '' COMMENT '姓名', `email` varchar(30) NOT NULL DEFAULT '' COMMENT '郵箱', `is_admin` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否是超級管理員 1表示是 0 表示不是', `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`), KEY `idx_email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶表';
角色表
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 `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 `idx_uid` (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶角色表';
權限詳情表
CREATE TABLE `access` ( `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 `role_access` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `role_id` int(11) NOT NULL DEFAULT '0' COMMENT '角色id', `access_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 `idx_role_id` (`role_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色權限表';
用戶操作記錄表
CREATE TABLE `app_access_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` bigint(20) NOT NULL DEFAULT '0' COMMENT '品牌UID', `target_url` varchar(255) NOT NULL DEFAULT '' COMMENT '訪問的url', `query_params` longtext NOT NULL COMMENT 'get和post參數', `ua` varchar(255) NOT NULL DEFAULT '' COMMENT '訪問ua', `ip` varchar(32) NOT NULL DEFAULT '' COMMENT '訪問ip', `note` varchar(1000) NOT NULL DEFAULT '' COMMENT 'json格式備注字段', `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_uid` (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶操作記錄表';
本系統所有頁面都是需要登錄之后才能訪問的, 在框架中加入統一驗證方法
public function beforeAction($action) { $login_status = $this->checkLoginStatus(); if ( !$login_status && !in_array( $action->uniqueId,$this->allowAllAction ) ) { if(Yii::$app->request->isAjax){ $this->renderJSON([],"未登錄,請返回用戶中心",-302); }else{ $this->redirect( UrlService::buildUrl("/user/login") );//返回到登錄頁面 } return false; } //保存所有的訪問到數據庫當中 $get_params = $this->get( null ); $post_params = $this->post( null ); $model_log = new AppAccessLog(); $model_log->uid = $this->current_user?$this->current_user['id']:0; $model_log->target_url = isset( $_SERVER['REQUEST_URI'] )?$_SERVER['REQUEST_URI']:''; $model_log->query_params = json_encode( array_merge( $post_params,$get_params ) ); $model_log->ua = isset( $_SERVER['HTTP_USER_AGENT'] )?$_SERVER['HTTP_USER_AGENT']:''; $model_log->ip = isset( $_SERVER['REMOTE_ADDR'] )?$_SERVER['REMOTE_ADDR']:''; $model_log->created_time = date("Y-m-d H:i:s"); $model_log->save( 0 ); /** * 判斷權限的邏輯是 * 取出當前登錄用戶的所屬角色, * 在通過角色 取出 所屬 權限關系 * 在權限表中取出所有的權限鏈接 * 判斷當前訪問的鏈接 是否在 所擁有的權限列表中 */ //判斷當前訪問的鏈接 是否在 所擁有的權限列表中 if( !$this->checkPrivilege( $action->getUniqueId() ) ){ $this->redirect( UrlService::buildUrl( "/error/forbidden" ) ); return false; } return true; }
檢查是否有訪問指定鏈接的權限
public function checkPrivilege( $url ){ //如果是超級管理員 也不需要權限判斷 if( $this->current_user && $this->current_user['is_admin'] ){ return true; } //有一些頁面是不需要進行權限判斷的 if( in_array( $url,$this->ignore_url ) ){ return true; } return in_array( $url, $this->getRolePrivilege( ) ); }
獲取某用戶的所有權限,取出指定用戶的所屬角色, 在通過角色取出所屬權限關系,在權限表中取出所有的權限鏈接
public function getRolePrivilege($uid = 0){ if( !$uid && $this->current_user ){ $uid = $this->current_user->id; } if( !$this->privilege_urls ){ $role_ids = UserRole::find()->where([ 'uid' => $uid ])->select('role_id')->asArray()->column(); if( $role_ids ){ //在通過角色 取出 所屬 權限關系 $access_ids = RoleAccess::find()->where([ 'role_id' => $role_ids ])->select('access_id')->asArray()->column(); //在權限表中取出所有的權限鏈接 $list = Access::find()->where([ 'id' => $access_ids ])->all(); if( $list ){ foreach( $list as $_item ){ $tmp_urls = @json_decode( $_item['urls'],true ); $this->privilege_urls = array_merge( $this->privilege_urls,$tmp_urls ); } } } } return $this->privilege_urls ; }
關于PHP與RBAC設計思路和數據表設計以及源碼是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。