中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP與RBAC設計思路和數據表設計以及源碼是怎樣的

發布時間:2021-10-11 11:22:44 來源:億速云 閱讀:151 作者:柒染 欄目:大數據

這篇文章將為大家詳細講解有關PHP與RBAC設計思路和數據表設計以及源碼是怎樣的,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

權限系統模塊對于互聯網產品是一個非常重要的功能,可以控制不同的角色合理的訪問不同的資源從而達到安全訪問的作用

權限控制有哪些模型

  • ACL

  • RBAC 基于角色的訪問控制

PHP與RBAC設計思路和數據表設計以及源碼是怎樣的

從上圖我們可以看出,ACL是用戶和權限直接關系的,而RBAC則是通過角色間接關聯用戶和權限的。所以我們注意到角色是RBAC系統的一個重要屬性。

什么是RBAC模型

RBAC(Role-Based Access Control,基于角色的訪問控制),就是用戶通過角色與權限進行關聯。簡單地說,一個用戶擁有若干角色,每一個角色擁有若干權限。這樣,就構造成“用戶-角色-權限”的授權模型。在這種模型中,用戶與角色之間,角色與權限之間,一般者是多對多的關系。

為什么要選擇RBAC模型

原因如下:

  • 方便用戶分組

  • 方便權限分配和回收

  • 擴展方便,可以滿足大部分業務需求

這些也就是我們在說權限管理前,應該先知道權限管理要有功能。

RBAC模型的關系圖

PHP與RBAC設計思路和數據表設計以及源碼是怎樣的

圖中有重要的RBAC模型5大屬性,分別是:
1 用戶屬性(張三、李四、王五)
2 角色屬性(銷售經理、銷售、前臺)
3 用戶與角色的關系(張三 是 銷售經理 、李四 王五 是 銷售)
4 權限(添加客戶、編輯客戶、刪除客戶,查看客戶)
5 權限與角色的關系(銷售 擁有 查看客戶的 權 限、銷售經理可以 查看/添加/刪除/編輯客戶的)

一個RBAC權限模塊,必然要實現三個功能

  • 用戶管理
    用戶列表
    添加用戶
    編輯用戶
    設置用戶角色

  • 角色管理 角色列表
    添加角色
    編輯角色
    設置角色權限

  • 權限管理
    權限列表
    新增權限
    編輯權限

如圖所示

PHP與RBAC設計思路和數據表設計以及源碼是怎樣的

數據表設計

用戶表

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設計思路和數據表設計以及源碼是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

上栗县| 布尔津县| 城口县| 霍林郭勒市| 茶陵县| 镇平县| 石台县| 高碑店市| 泸定县| 大石桥市| 博湖县| 商水县| 英吉沙县| 宝丰县| 花莲市| 建阳市| 晋宁县| 盐池县| 榆社县| 额济纳旗| 南丰县| 盐津县| 海口市| 岚皋县| 吴旗县| 株洲市| 罗山县| 宝坻区| 康乐县| 海丰县| 绩溪县| 平罗县| 南靖县| 镇原县| 濉溪县| 祁连县| 衡阳市| 韩城市| 教育| 昌图县| 合水县|