RBAC的详细分析网上一大堆。
一.表的设计
① sw_manager 后台用户管理员表
② sw_role 角色表
③ sw_auth 具体权限表
sw_manager 后台用户管理员表
# Host: localhost (Version: 5.5.53)
# Date: 2018-09-05 09:00:00
# Generator: MySQL-Front 5.3 (Build 4.234)
/*!40101 SET NAMES utf8 */;
#
# Structure for table "sw_manager"
#
DROP TABLE IF EXISTS `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 AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
#
# Data for table "sw_manager"
#
INSERT INTO `sw_manager` VALUES (1,'admin','123456',0,0),(2,'tom','123456',0,1),(3,'linken','123456',0,2),(4,'mary','123456',1387785044,2),(5,'yuehan','123456',1387785056,2);
sw_role 角色表
# Host: localhost (Version: 5.5.53)
# Date: 2018-09-05 09:03:14
# Generator: MySQL-Front 5.3 (Build 4.234)
/*!40101 SET NAMES utf8 */;
#
# Structure for table "sw_role"
#
DROP TABLE IF EXISTS `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 '权限ids,1,2,5',
`role_auth_ac` text COMMENT '模块-操作',
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
#
# Data for table "sw_role"
#
INSERT INTO `sw_role` VALUES (1,'经理','1,4,19,5,6,2,8,9,3,11,12','Goods-showlist,Goods-add,Goods-cate,Order-showlist,Order-print,Advert-showlist,Advert-position,Goods-upd'),(2,'主管','1,4,18,5,6,7,2,8,9,10','Goods-showlist,Goods-add,Goods-cate,User-comment,Order-showlist,Order-print,Order-add,Goods-del');
sw_auth 具体权限表
# Host: localhost (Version: 5.5.53)
# Date: 2018-09-05 09:04:54
# Generator: MySQL-Front 5.3 (Build 4.234)
/*!40101 SET NAMES utf8 */;
#
# Structure for table "sw_auth"
#
DROP TABLE IF EXISTS `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 AUTO_INCREMENT=22 DEFAULT CHARSET=utf8;
#
# Data for table "sw_auth"
#
INSERT INTO `sw_auth` VALUES (1,'商品管理',0,'','','1',0),(2,'订单管理',0,'','','2',0),(3,'广告管理',0,'','','3',0),(4,'商品列表',1,'Goods','showlist','1-4',1),(5,'添加商品',1,'Goods','add','1-5',1),(6,'商品分类',1,'Goods','cate','1-6',1),(7,'用户评论',1,'User','comment','1-7',1),(8,'订单列表',2,'Order','showlist','2-8',1),(9,'订单打印',2,'Order','print','2-9',1),(10,'添加订单',2,'Order','add','2-10',1),(11,'广告列表',3,'Advert','showlist','3-11',1),(12,'广告位置',3,'Advert','position','3-12',1),(13,'系统管理',0,'','','13',0),(14,'角色管理',13,'Role','showlist','13-14',1),(15,'权限管理',13,'Auth','showlist','13-15',1),(16,'会员管理',0,'User','showlist','16',0),(17,'商品回收站',1,'Goods','huishou','1-17',1),(18,'商品删除',4,'Goods','del','1-4-18',2),(19,'商品修改',4,'Goods','upd','1-4-19',2),(20,'管理员列表',13,'Manager','showlist','13-20',1),(21,'apple',5,'8x','aa','1-5-21',2);
操作:
a.根据用户登录信息进行相应权限展示
- 根据权限ids信息查询具体权限信息进而显示
- 根据角色id信息获得权限列表ids信息
- 根据session信息获得角色role_id信息
- 用户登录系统显示权限信息 $_SESSION[‘mg_id’]
- 超级管理员不要进行权限控制admin。
//根据session用户id信息查询角色id信息
$sql = "select * from sw_manager where mg_id=".$_SESSION['mg_id'];
$minfo = D()->query($sql);
$role_id = $minfo[0]['mg_role_id'];
//根据角色信息获得权限ids的信息
$sql = "select * from sw_role where role_id=".$role_id;
$rinfo = D()->query($sql);
$auth_ids = $rinfo[0]['role_auth_ids'];
//根据$auth_ids查询全部拥有的权限信息
//① 获得顶级权限
$sql = "select * from sw_auth where auth_level=0 ";
//如果是admin管理员要现实全部权限
if($_SESSION['mg_id'] != 1){
$sql .= " and auth_id in ($auth_ids)";
}
$p_info = D()->query($sql);
//② 获得次顶级权限
$sql = "select * from sw_auth where auth_level=1";
//如果是admin管理员要现实全部权限
if($_SESSION['mg_id'] != 1){
$sql .= " and auth_id in ($auth_ids)";
}
$s_info = D()->query($sql);
$this -> assign('pauth_info',$p_info);
$this -> assign('sauth_info',$s_info);
$this -> display();
b.控制翻墙浏览以及超级管理员不设限
虽然显示是各类角色应该看到的权限,但是可以通过修改url来查看不属于自己的权限。这个时候需要在所有操作前进行判断,具体做法,加个中间介质(父控制器类),所有操作必须通过它。
<?php
//普通控制器的父类
namespace Component;
use Think\Controller;
class AdminController extends Controller{
//构造方法
function __construct() {
//先执行父类的构造方法,否则系统要报错
//因为原先的构造方法默认是被执行的
parent::__construct();
//CONTROLLER_NAME ---Goods
//ACTION_NAME ----showlist
//当前请求操作
if(!$_SESSION['mg_id']){
$this -> error('未登录',U("Manager/login"));
}else{
$now_ac = CONTROLLER_NAME."-".ACTION_NAME;
if($_SESSION['mg_id'] != 1){
//过滤控制器和方法,避免用户非法请求
//通过角色获得用户可以访问的控制器和方法信息
$sql ="select role_auth_ac from sw_manager a join sw_role b on a.mg_role_id=b.role_id where a.mg_id=".$_SESSION['mg_id'];
$auth_ac = D()->query($sql);
$auth_ac = $auth_ac[0]['role_auth_ac'];
//判断$now_ac是否在$auth_ac字符串里边有出现过
//strpos函数如果返回false是没有出现,返回0 1 2 3表示有出现
//管理员不限制
//默认以下权限没有限制
//Index/left Index/right Index/head Index/index Manager/login
$allow_ac = array('Index-left','Index-right','Index-head','Index-index','Manager-login');
if(!in_array($now_ac,$allow_ac) && $_SESSION['mg_id'] !=1 && strpos($auth_ac,$now_ac) === false){
$this -> error('没有权限访问',U("Index/index"));
}
}
}
}
}