~~~
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
// $Id: RBAC.class.php 2504 2011-12-28 07:35:29Z liu21st $
/**
+------------------------------------------------------------------------------
* 基于角色的數據庫方式驗證類
+------------------------------------------------------------------------------
* @category ORG
* @package ORG
* @subpackage Util
* @author liu21st <liu21st@gmail.com>
* @version $Id: RBAC.class.php 2504 2011-12-28 07:35:29Z liu21st $
+------------------------------------------------------------------------------
*/
// 配置文件增加設置
// ADMIN_AUTH_KEY 管理員認證SESSION標記
// USER_AUTH_KEY 用戶認證SESSION標記
//
// $_SESSION[C('USER_AUTH_KEY')] 用來保存登陸成功后的用戶ID
// $_SESSION[C('ADMIN_AUTH_KEY')] 用來保存登陸成功后的管理員ID
//
// USER_AUTH_ON 是否需要認證
// USER_AUTH_TYPE 認證類型,1是登陸認證,2是實時認證
// USER_AUTH_MODEL 用戶模型名稱
// GUEST_AUTH_ON 是否開啟游客授權訪問
// GUEST_AUTH_ID 游客的用戶ID
//
// REQUIRE_AUTH_MODULE 需要認證模塊(若定義了,則只驗證給出的模塊;否則驗證所有模塊)
// NOT_AUTH_MODULE 無需認證模塊(若定義了“需要認證模塊”則本條定義無效)
// REQUIRE_AUTH_ACTION 需要認證操作(若定義了,則只驗證給出的操作;否則驗證所有操作)
// NOT_AUTH_ACTION 無需認證操作(若定義了“需要認證操作”則本條定義無效)
//
// USER_AUTH_GATEWAY 認證網關,如果用戶沒有登錄則轉到這頁(URL路由規則)
// RBAC_DB_DSN 數據庫連接DSN
// RBAC_ROLE_TABLE 角色表名稱
// RBAC_USER_TABLE 用戶表名稱(應該是用戶、用戶組關系表)
// RBAC_ACCESS_TABLE 權限表名稱
// RBAC_NODE_TABLE 節點表名稱
//
/*
-- --------------------------------------------------------
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;
*/
class RBAC {
// 認證方法
// 得到需要鑒別的用戶列表
// 即按照map中給的條件查詢用戶表(由USER_AUTH_MODEL給出)
static public function authenticate($map,$model='')
{
if(empty($model)) $model = C('USER_AUTH_MODEL');
//使用給定的Map進行認證
return M($model)->where($map)->find();
}
// 用于檢測用戶權限的方法,并保存到Session中
// 將當前操作用戶擁有的所有權限保存到$_SESSION['_ACCESS_LIST']里
// 開銷巨大,是對getAccessList的封裝
static function saveAccessList($authId=null)
{
if(null===$authId) $authId = $_SESSION[C('USER_AUTH_KEY')];
// 如果使用普通權限模式,保存當前用戶的訪問權限列表
// 對管理員開放所有權限
// 如果是實時認證(USER_AUTH_TYPE==2),則每次Decision的時候都刷新ACCESS_LIST,
// 就不用在這刷新了
if(C('USER_AUTH_TYPE') !=2 && !$_SESSION[C('ADMIN_AUTH_KEY')] )
$_SESSION['_ACCESS_LIST'] = RBAC::getAccessList($authId);
return ;
}
// 取得模塊的所屬記錄訪問權限列表 返回有權限的記錄ID數組
// 返回當前模塊中當前用戶所擁有的權限列表
// 開銷巨大,是對getModuleAccessList的封裝
static function getRecordAccessList($authId=null,$module='') {
if(null===$authId) $authId = $_SESSION[C('USER_AUTH_KEY')];
if(empty($module)) $module = MODULE_NAME;
//獲取權限訪問列表
$accessList = RBAC::getModuleAccessList($authId,$module);
return $accessList;
}
//檢查當前操作是否需要認證,需要則返回true,不需要則返回false
static function checkAccess()
{
//如果項目要求認證,并且當前模塊需要認證,則進行權限認證
if( C('USER_AUTH_ON') ){
$_module = array();
$_action = array();
if("" != C('REQUIRE_AUTH_MODULE')) {
//需要認證的模塊
$_module['yes'] = explode(',',strtoupper(C('REQUIRE_AUTH_MODULE')));
}else {
//無需認證的模塊
$_module['no'] = explode(',',strtoupper(C('NOT_AUTH_MODULE')));
}
//檢查當前模塊是否需要認證
if((!empty($_module['no']) && !in_array(strtoupper(MODULE_NAME),$_module['no'])) ||
(!empty($_module['yes']) && in_array(strtoupper(MODULE_NAME),$_module['yes']))) {
if("" != C('REQUIRE_AUTH_ACTION')) {
//需要認證的操作
$_action['yes'] = explode(',',strtoupper(C('REQUIRE_AUTH_ACTION')));
}else {
//無需認證的操作
$_action['no'] = explode(',',strtoupper(C('NOT_AUTH_ACTION')));
}
//檢查當前操作是否需要認證
if((!empty($_action['no']) && !in_array(strtoupper(ACTION_NAME),$_action['no'])) ||
(!empty($_action['yes']) && in_array(strtoupper(ACTION_NAME),$_action['yes']))) {
return true;
}else {
return false;
}
}else {
return false;
}
}
return false;
}
// 檢查用戶是否登錄
// 如果沒有登錄,則嘗試進行“游客”登錄;如果無法以游客身份登錄,則跳轉到認證網關
static public function checkLogin() {
//檢查當前操作是否需要認證
if(RBAC::checkAccess()) {
//檢查認證識別號
if(!$_SESSION[C('USER_AUTH_KEY')]) {
if(C('GUEST_AUTH_ON')) {
// 開啟游客授權訪問
if(!isset($_SESSION['_ACCESS_LIST']))
// 保存游客權限
RBAC::saveAccessList(C('GUEST_AUTH_ID'));
}else{
// 禁止游客訪問跳轉到認證網關
redirect(PHP_FILE.C('USER_AUTH_GATEWAY'));
}
}
}
return true;
}
// 權限認證的過濾器方法
// 檢查當前操作是否被允許,返回bool值
static public function AccessDecision($appName=APP_NAME)
{
//檢查是否需要認證
if(RBAC::checkAccess()) {
//存在認證識別號,則進行進一步的訪問決策
$accessGuid = md5($appName.MODULE_NAME.ACTION_NAME);
if(empty($_SESSION[C('ADMIN_AUTH_KEY')])) {
if(C('USER_AUTH_TYPE')==2) {
//實時認證模式,刷新ACCESS_LIST
//加強驗證和即時驗證模式 更加安全 后臺權限修改可以即時生效
//通過數據庫進行訪問檢查
$accessList = RBAC::getAccessList($_SESSION[C('USER_AUTH_KEY')]);
}else {
//登錄驗證模式,使用登錄后填充的ACCESS_LIST
// 如果是管理員或者當前操作已經認證過,無需再次認證
if( $_SESSION[$accessGuid]) {
return true;
}
$accessList = $_SESSION['_ACCESS_LIST'];
}
//判斷是否為組件化模式,如果是,驗證其全模塊名
$module = defined('P_MODULE_NAME')? P_MODULE_NAME : MODULE_NAME;
if(!isset($accessList[strtoupper($appName)][strtoupper($module)][strtoupper(ACTION_NAME)])) {
//沒有權限
$_SESSION[$accessGuid] = false;
return false;
}
else {
$_SESSION[$accessGuid] = true;
}
}else{
//管理員無需認證
return true;
}
}
return true;
}
/**
+----------------------------------------------------------
* 取得當前認證號的所有權限列表
* (得到指定用戶擁有的所有操作權限)
+----------------------------------------------------------
* @param integer $authId 用戶ID
+----------------------------------------------------------
* @access public
+----------------------------------------------------------
*/
static public function getAccessList($authId)
{
// Db方式權限數據
$db = Db::getInstance(C('RBAC_DB_DSN'));
$table = array('role'=>C('RBAC_ROLE_TABLE'),
'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'),'node'=>C('RBAC_NODE_TABLE'));
// 首先檢查該用戶所在用戶組擁有權限的所有項目
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=1 and node.status=1";
$apps = $db->query($sql);
$access = array();
foreach($apps as $key=>$app) {
$appId = $app['id'];
$appName = $app['name'];
// 讀取項目的模塊權限
$access[strtoupper($appName)] = array();
// 再檢查每個有權限的項目下面所有有權限的模塊
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=2 and node.pid={$appId} and node.status=1";
$modules = $db->query($sql);
// 判斷是否存在公共模塊的權限
$publicAction = array();
foreach($modules as $key=>$module) {
$moduleId = $module['id'];
$moduleName = $module['name'];
if('PUBLIC'== strtoupper($moduleName)) {
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
$rs = $db->query($sql);
foreach ($rs as $a){
$publicAction[$a['name']] = $a['id'];
}
unset($modules[$key]);
break;
}
}
// 再檢查每個有權限的模塊(除公共模塊)下面所有有權限的操作,依次讀取模塊的操作權限
foreach($modules as $key=>$module) {
$moduleId = $module['id'];
$moduleName = $module['name'];
$sql = "select node.id,node.name from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ,".
$table['node']." as node ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
$rs = $db->query($sql);
$action = array();
foreach ($rs as $a){
$action[$a['name']] = $a['id'];
}
// 和公共模塊的操作權限合并
$action += $publicAction;
$access[strtoupper($appName)][strtoupper($moduleName)] = array_change_key_case($action,CASE_UPPER);
}
}
return $access;
}
/**
+----------------------------------------------------------
* 讀取指定模塊、指定用戶擁有的所有權限列表
+----------------------------------------------------------
* @param integer $authId 用戶ID
* @param string $module 模塊名
+----------------------------------------------------------
* @access public
+----------------------------------------------------------
*/// 讀取指定模塊、指定用戶擁有的所有權限列表
static public function getModuleAccessList($authId,$module) {
// Db方式
$db = Db::getInstance(C('RBAC_DB_DSN'));
$table = array('role'=>C('RBAC_ROLE_TABLE'),'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'));
$sql = "select access.node_id from ".
$table['role']." as role,".
$table['user']." as user,".
$table['access']." as access ".
"where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.module='{$module}' and access.status=1";
$rs = $db->query($sql);
$access = array();
foreach ($rs as $node){
$access[] = $node['node_id'];
}
return $access;
}
}
~~~
- 前端工程師
- HTML
- 使用meta實現頁面的定時刷新或跳轉
- 表單相關
- 表單元素input、按鈕、文字完美垂直居中對齊方法
- CSS
- 相關工具網站
- JS
- jQuery
- 第1章 初始jQuery
- 環境搭建
- jQuery對象與DOM對象
- jQuery對象轉化成DOM對象
- DOM對象轉化成jQuery對象
- 第2章 jQuery選擇器
- id選擇器
- 類選擇器
- 元素選擇器
- 全選擇器(*選擇器)
- 層級選擇器
- 基本篩選選擇器
- 內容篩選選擇器
- 可見性篩選選擇器
- 屬性篩選選擇器
- 子元素篩選選擇器
- 表單元素選擇器
- 表單對象屬性篩選選擇器
- 特殊選擇器this
- 第3章 jQuery的屬性與樣式
- 元素的數據存儲
- 問題解決方案
- 解決innerHTML包含的js代碼不能被執行的問題
- webpackdoc
- 前端開發框架
- Bootstrap 3.3.6
- 起步
- 全局 CSS 樣式
- 概覽
- 柵格系統
- PHP
- PHP入門篇
- 基礎總結
- PHP環境變量$_SERVER和系統常量詳細說明
- PHP進階篇
- 數組
- 函數
- 類
- 字符串操作
- 正則表達式
- 會話控制
- 文件系統
- 日期和時間
- 圖形圖像操作
- PHP異常處理
- 數據庫操作
- WEB在線文件管理器
- PHP文件操作
- 獲取首層目錄信息
- 獲取文件信息
- 列表顯示文件及大小
- PHP與MySQL關系大揭秘
- PHP支持哪些數據庫
- 數據庫擴展
- 連接MySQL數據庫
- 執行MySQL查詢
- 插入新數據到MySQL中
- MVC架構模式分析與設計
- Smarty模版語法
- Smarty的基本語法
- Smarty的條件判斷語句
- Smarty的循環語句
- Smarty的文件引用
- Smarty類和對象賦值與使用
- Smarty函數的使用
- functions函數插件的定義和使用
- modifiers變量調節器插件的定義和使用
- block functions區塊函數插件的定義和使用
- Smarty實例
- MVC微型框架的建立
- 網絡摘抄
- PHPExcel如何讀取超大excel文件
- Composer
- Composer技巧
- PHP 開發者該知道的 5 個 Composer 小技巧
- composer常用命令
- Composer使用方法整理(Cy23)
- 利用Composer一步一步搭建自己的PHP框架
- ThinkPHP
- ThinkPHP中RBAC類詳解(一)
- 附:添加注釋版RBAC類源碼
- 常見問題
- 常見方法
- thinkphp 合并兩個字段組合成一個臨時字段concat函數
- ThinkPHP Where 條件中使用表達式
- 編程相關工具
- Eclipse
- Eclipse或Zendstudio漢化
- Zend studio
- Zendstudio快捷鍵
- Zend Studio實用快捷鍵一覽表
- Sublime text
- Sublime text快捷鍵
- 16 個 Sublime Text 快捷鍵
- Emmet的用法及相關語法
- VS Code
- 數據庫
- MySql
- 問題匯總
- mysql創建存儲過程失敗1307錯誤解決
- Mysql出現Field * doesn't have a default value解決辦法
- mysql:ADO連接mysql數據庫,驅動程序和ODBC數據源問題
- 自己如何正確獲取MYSQL的ADO連接字符串
- 網上摘抄
- mysql 存在更新 不存在插入
- Mysql字符串字段中是否包含某個字符串,用 find_in_set
- mysql字段類型對應的數字編號
- 5.7mysql group分組查詢錯誤問題
- mysql常用操作語句
- SQL2005
- SQL常見錯誤
- 使用 sp_change_users_login 修復產生的孤 立賬戶 & 還原中的孤立用戶
- ASP
- Url編碼解碼函數合集 含utf-8和gb2312
- 其他前端相關技巧
- 聯機查看 Office 文檔
- 服務器配置
- windows
- 服務器安裝
- XAMPP自帶TOMCAT插件可以支持php+java
- IIS
- iis7服務器,客戶端無法下載exe文件的解決之道
- Linux
- ubuntu
- Linux安裝JDK
- 輔助開發工具
- Git