首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

yotaku 開發日誌(一):ThinkPHP 基於角色的權限控制 (RBAC) 實踐

     編輯:PHP 相關知識

項目背景

記錄 2015-12-18 學習 ThinkPHP 框架過程中,實現基於角色的訪問控制(RBAC)的數據庫設計、數據初始化、後台邏輯與前端模板渲染全流程。

一、數據庫設計

1. 管理員表 sw_manager

CREATE TABLE `sw_manager` (
  `mg_id` int(11) NOT NULL AUTO_INCREMENT,
  `mg_name` varchar(32) NOT NULL,
  `mg_pwd` varchar(32) NOT NULL,
  `mg_time` int(10) unsigned NOT NULL COMMENT '註冊時間',
  `mg_role_id` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '角色ID',
  PRIMARY KEY (`mg_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

示例數據:

mg_idmg_namemg_pwdmg_timemg_role_id
0creatint12325874135471
1yotaku1232587449844

2. 權限表 sw_auth

CREATE TABLE `sw_auth` (
  `auth_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
  `auth_name` varchar(20) NOT NULL COMMENT '權限名稱',
  `auth_pid` smallint(6) unsigned NOT NULL COMMENT '父ID',
  `auth_c` varchar(32) NOT NULL DEFAULT '' COMMENT '控制器',
  `auth_a` varchar(32) NOT NULL DEFAULT '' COMMENT '操作方法',
  `auth_path` varchar(32) NOT NULL COMMENT '全路徑',
  `auth_level` tinyint(4) NOT NULL DEFAULT '0' COMMENT '級別',
  PRIMARY KEY (`auth_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

字段含義:auth_level=0 為頂級模塊,=1 為具體操作節點。

3. 角色表 sw_role

CREATE TABLE `sw_role` (
  `role_id` smallint(6) unsigned NOT NULL AUTO_INCREMENT,
  `role_name` varchar(20) NOT NULL COMMENT '角色名稱',
  `role_auth_ids` varchar(128) NOT NULL DEFAULT '' COMMENT '權限ID列表,如 1,3,9',
  `role_auth_ac` text COMMENT '控制器-操作對,如 Goods-show,Goods-cate',
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二、權限數據初始化

頂級模塊

INSERT INTO `sw_auth` VALUES
(100, '產品中心', 0, '', '', '100', 0),
(101, '高級管理', 0, '', '', '101', 0),
(102, '系統管理', 0, '', '', '102', 0),
(103, '權限管理', 0, '', '', '103', 0);

二級操作節點

INSERT INTO `sw_auth` VALUES
(104, '產品展示', 100, 'Goods', 'show', '100-104', 1),
(105, '最新產品', 100, 'Goods', 'showlist', '100-105', 1),
(106, '分類管理', 100, 'Goods', 'cate', '100-106', 1),
(107, '用戶留言', 101, 'Goods', 'words', '101-107', 1),
(108, '留言簿', 101, 'Goods', 'wordsbook', '101-108', 1),
(109, '基本設置', 102, 'Goods', 'set', '102-109', 1),
(110, '樣式管理', 102, 'Goods', 'css', '102-110', 1),
(111, '用戶列表', 103, 'Goods', 'userlist', '103-111', 1),
(112, '角色管理', 103, 'Goods', 'role', '103-112', 1),
(113, '權限列表', 103, 'Goods', 'auth', '103-113', 1);

角色數據

INSERT INTO `sw_role` VALUES
(10, '站主', '100,101,102,103,104,105,106,107,108,109,110,111,112,113',
     'Goods-show,Goods-showlist,Goods-cate,Goods-words,Goods-wordsbook,Goods-set,Goods-css'),
(11, '管理員', '100,102,104,105,109',
     'Goods-showlist,Goods-cate,Goods-css'),
(12, '版主', '100,101,103,106,108,113',
     'Goods-show,Goods-set');

三、後台權限邏輯

// Index 控制器 left 方法
$mg_id = session('admin_id');
$manager_info = D('Manager')->find($mg_id);
$role_id = $manager_info['mg_role_id'];

$role_info = D('Role')->find($role_id);
$auth_ids = $role_info['role_auth_ids'];

// 查詢頂級模塊
$auth_infoA = D('Auth')->where("auth_level=0 AND auth_id IN ($auth_ids)")->select();
// 查詢二級節點
$auth_infoB = D('Auth')->where("auth_level=1 AND auth_id IN ($auth_ids)")->select();

$this->assign('auth_infoA', $auth_infoA);
$this->assign('auth_infoB', $auth_infoB);
$this->display();

四、前端模板渲染

模板 left.html(Smarty 語法):

{foreach $auth_infoA as $k=>$v}
{$v.auth_name}
{foreach $auth_infoB as $k2=>$v2} {if $v2.auth_pid == $v.auth_id} {/if} {/foreach} {/foreach}

配合 JavaScript expand(id) 控制二級菜單展開/收起,實現經典左側導航樹。

五、總結

此 RBAC 實現採用「角色-權限ID列表」與「控制器-操作對」雙重存儲,查詢時按層級分兩次 SQL 獲取,模板雙重循環渲染樹狀菜單。優點:邏輯清晰、易擴展;缺點:權限變更需同步兩字段、深層級菜單需遞歸查詢。後續可優化為 Closure Table 或引入 Casbin 等專業授權庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved