RBAC权限管理

来源:互联网 发布:熊猫智能采集软件 编辑:程序博客网 时间:2024/05/01 17:35

1. 简介

RBAC是Role-Based Access Control的首字母,即基于角色的访问控制,是最简单的权限管理解决方案。它对权限的控制精度一般为节点。

基本模型为用户-角色-权限(节点),用户和角色之间、角色和节点之间都是多对多的关系。

实现原理:

在用户登录的时候,将用户拥有的权限(可访问的模块、控制器和方法),保存到session中;
在用户访问某个页面或按钮时,进行权限的验证,如果没有权限,则禁止访问。

2. 基本用法

以ThinkPHP3.2.3为例,进行简单介绍。

RBAC类文件为ThinkPHP\Library\Org\Util\Rbac.class.php,默认的认证方式为登录验证。

建立五张数据表。

# 用户表CREATE TABLE IF NOT EXISTS `think_user` (  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',  `username` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名',  `password` char(32) NOT NULL DEFAULT '' COMMENT '密码',  `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态:0禁用,1正常',  `login_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最近一次登录时间',  `login_ip` int(11) NOT NULL DEFAULT '0' COMMENT '最近一次登录ip',  PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='用户表';# 角色表(即用户组表)CREATE TABLE IF NOT EXISTS `think_role` (  `id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色id',  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '角色名称',  `pid` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '父角色的id',  `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态:0禁用,1正常',  `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',  PRIMARY KEY (`id`),  KEY `pid` (`pid`),  KEY `status` (`status`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='角色表(即用户组表)';# 角色用户表CREATE TABLE IF NOT EXISTS `think_role_user` (  `role_id` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '角色id',  `user_id` mediumint(8) unsigned NOT NULL DEFAULT '0' COMMENT '用户id',  KEY `group_id` (`role_id`),  KEY `user_id` (`user_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='角色用户表';# 节点表CREATE TABLE IF NOT EXISTS `think_node` (  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT COMMENT '节点id',  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '节点的名称(英文)',  `title` varchar(15) NOT NULL DEFAULT '' COMMENT '节点的中文名称',  `pid` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT '父节点的id',  `sort` smallint(5) unsigned NOT NULL DEFAULT '50' COMMENT '排序的权重',  `level` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '节点的级别:1模块,2控制器,3方法',  `status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '状态:0禁用,1正常',  PRIMARY KEY (`id`),  KEY `level` (`level`),  KEY `pid` (`pid`),  KEY `status` (`status`),  KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='节点表';# 权限表(即角色节点表)CREATE TABLE IF NOT EXISTS `think_access` (  `role_id` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '角色id',  `node_id` smallint(6) unsigned NOT NULL DEFAULT '0' COMMENT '节点id',  `level` tinyint(1) NOT NULL DEFAULT '1' COMMENT '级别',  `module` varchar(20) NOT NULL DEFAULT '',  KEY `groupId` (`role_id`),  KEY `nodeId` (`node_id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='权限表(即角色节点表)';

RABC权限管理的基本操作:

  • 用户(增、删、改、查)
  • 角色(增、删、改、查)
  • 节点(增、删、改、查)
  • 给角色分配权限

测试数据如下:

用户表(think_user):

id username password status login_time login_ip 1 admin e10adc3949ba59abbe56e057f20f883e 1 0 0 2 user01 e10adc3949ba59abbe56e057f20f883e 1 1497234282 2130706433 3 user02 e10adc3949ba59abbe56e057f20f883e 1 0 0 4 user03 e10adc3949ba59abbe56e057f20f883e 1 1497233938 2130706433

角色表(think_role):

id name pid status remark 1 白金会员 0 1 2 黄金会员 0 1 3 普通会员 0 1

角色用户表(think_role_user):

role_id user_id 2 2 3 3 3 4

节点表(think_node):

id name title pid sort level status 1 Admin Admin模块 0 50 1 1 2 Home Home模块 0 50 1 1 3 Index Index控制器 1 50 2 1 4 index 后台首页 3 50 3 1 5 test 测试页面 3 50 3 1

角色节点表(think_access):

role_id node_id level module 3 1 1 3 3 2 3 4 3 3 5 3

应用入口文件index.php,内容如下:

<?php// 检测PHP环境if(version_compare(PHP_VERSION,'5.3.0','<'))  die('require PHP > 5.3.0 !');// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为falsedefine('APP_DEBUG',True);// 定义应用目录define('APP_PATH','./Application/');// 绑定Admin模块到当前入口文件(这样,访问入口文件后,就可以自动生成该模块的目录)// 同时,设定入口文件的默认访问模块为Admin,优先级最高(高于配置文件中的DEFAULT_MODULE)define('BIND_MODULE','Admin');// 引入ThinkPHP入口文件require './ThinkPHP/ThinkPHP.php';

应用配置文件config.php,内容如下:

<?phpreturn array(    //'配置项'=>'配置值'    // 允许访问的模块列表和默认模块    'MODULE_ALLOW_LIST' => array('Home','Admin'),    'DEFAULT_MODULE' => 'Admin',    // 加载扩展配置文件    'LOAD_EXT_CONFIG' => 'rbac,db',);

扩展配置文件rbac.php(rbac配置),内容如下:

<?phpreturn array(        // 是否开启权限认证        'USER_AUTH_ON'          => true,        // 认证方式(1登录验证,2即时验证)        'USER_AUTH_TYPE'        => 1,            // 认证识别号        'USER_AUTH_KEY'         => 'uid',        // 超级管理员识别号        'ADMIN_AUTH_KEY'        => 'admin',        // 是否开启游客授权访问        'GUEST_AUTH_ON'         => false,          // 游客认证的id        'GUEST_AUTH_ID'         => 0,        // 需要认证的控制器(多个用逗号分隔)(可不配置)        'REQUIRE_AUTH_MODULE'   => '',        // 无需认证的控制器(可不配置)        'NOT_AUTH_MODULE'       => '',        // 认证网关        'USER_AUTH_GATEWAY'     => 'Public/login',        // 用户认证模型(用户表的名称,不要表前缀)        'USER_AUTH_MODEL'       => 'user',            // 角色表的名称(带表前缀)        'RBAC_ROLE_TABLE'       => 'think_role',        // 用户角色表的名称(带表前缀)        'RBAC_USER_TABLE'       => 'think_role_user',        // 权限表的名称(带表前缀)        'RBAC_ACCESS_TABLE'     => 'think_access',        // 节点表的名称(带表前缀)        'RBAC_NODE_TABLE'       => 'think_node',);

扩展配置文件db.php(数据库配置),内容如下:

<?phpreturn array(        // 数据库配置        'DB_TYPE'               =>  'mysql',        // 数据库类型        'DB_HOST'               =>  '127.0.0.1',    // 服务器地址        'DB_NAME'               =>  'test',         // 数据库名        'DB_USER'               =>  'root',     // 用户名        'DB_PWD'                =>  '123456',   // 密码        'DB_PORT'               =>  '3306',     // 端口        'DB_PREFIX'             =>  'think_',   // 数据库表前缀);

D:\xampp\htdocs\test\Application\Admin\Controller\PublicController.class.php控制器的代码如下:

<?phpnamespace Admin\Controller;use Think\Controller;use Org\Util\Rbac;class PublicController extends Controller {    /**     * 用户登录页面     */    public function login() {        $this->display();    }    /**     * 登录提交的地址     */    public function login_submit() {        if(!IS_POST) $this->error('页面不存在,请稍后再试', U('Admin/Public/login'));        $username = I('username','');        $password = I('password','');        $user_info = M('user')->where("username = '$username' AND password = '".md5($password)."'")->find();        if(!$user_info) $this->error('用户名或密码错误', U('Admin/Public/login'));        if(!$user_info['status']) $this->error('该用户已被禁用,暂时不可登录', U('Admin/Public/login'));        // 更新登录信息        M('user')->save(array("id"=> $user_info["id"], "login_time"=> time(), "login_ip" => ip2long(get_client_ip())));        // 写入session        session(C('USER_AUTH_KEY'), $user_info['id']);   // 用户id(uid)        session('username', $user_info['username']);   // 用户名        //如果为超级管理员,则无需权限认证        if($user_info['username'] == C('ADMIN_AUTH_KEY')) {            session(C('ADMIN_AUTH_KEY'), true);        }        // 引入Rbac类        import('ORG.Util.Rbac');        // 查询用户拥有的权限并存入session        Rbac::saveAccessList();        $this->success('登录成功', U('Admin/Index/index'));    }}

D:\xampp\htdocs\test\Application\Admin\Controller\CommonController.class.php控制器的代码如下:

<?phpnamespace Admin\Controller;use Think\Controller;use Org\Util\Rbac;/** * @author Administrator * 所有需要进行权限验证的控制器,使其继承CommonController即可 */class CommonController extends Controller {    /**     * ThinkPHP中提供了_initialize()方法,在类初始化时,_initialize()方法会自动执行     */    protected function _initialize() {        // 引入Rbac类        import('ORG.Util.Rbac');        // 进行权限验证        $res = Rbac::AccessDecision();        if($res===false) $this->error("无访问权限", U('Public/login'));    }}

D:\xampp\htdocs\test\Application\Admin\Controller\IndexController.class.php控制器的代码如下:

<?phpnamespace Admin\Controller;class IndexController extends CommonController {    /**     * 后台首页     * http://127.0.0.1/test/index.php/index/index     */    public function index() {        dump(session());        echo '这是首页!';    }    /**     * 测试页面     * http://127.0.0.1/test/index.php/index/test     */    public function test() {        echo MODULE_NAME.'<br/>';        echo CONTROLLER_NAME.'<br/>';        echo ACTION_NAME.'<br/>';        echo '测试页面';    }}
原创粉丝点击