码迷,mamicode.com
首页 > Web开发 > 详细

ThinkPHP RBAC权限管理机制

时间:2015-10-30 14:16:59      阅读:365      评论:0      收藏:0      [点我收藏+]

标签:

RBAC是ThinkPHP很好用的后台权限管理的,话不多说,实现方法如下,也方便以后自己查询使用:

1、新建4个数据库表

    self_role权限表

CREATE TABLE `self_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 AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `self_role` VALUES (1, 超级管理员, 0, 1, 超级管理权限);
INSERT INTO `self_role` VALUES (2, 普通管理员, 0, 1, 普通管理权限);
INSERT INTO `self_role` VALUES (3, 注册用户, 0, 1, 注册管理权限);

self_role_user表:权限(self_role)与用户表(self_user)的关系表

CREATE TABLE `self_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;

INSERT INTO `self_role_user` VALUES (1, 3);
INSERT INTO `self_role_user` VALUES (2, 4);

self_node表:权限分配表

CREATE TABLE `self_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 AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

INSERT INTO `self_node` VALUES (1, Admin, 后台项目, 1, 项目权限, 0, 0, 1);
INSERT INTO `self_node` VALUES (2, Index, 默认控制模块, 1, 控制器, 0, 1, 2);
INSERT INTO `self_node` VALUES (3, index, 默认操作, 1, 操作动作, 0, 2, 3);
INSERT INTO `self_node` VALUES (4, User, 用户控制模块, 1, 控制器, 0, 1, 2);
INSERT INTO `self_node` VALUES (5, Section, 单元控制模块, 1, 控制器, 0, 1, 2);
INSERT INTO `self_node` VALUES (6, index, 用户默认操作, 1, 操作动作, 0, 4, 3);
INSERT INTO `self_node` VALUES (7, add, 用户添加操作, 1, 操作动作, 0, 4, 3);
INSERT INTO `self_node` VALUES (8, index, 单元默认操作, 1, 操作动作, 0, 5, 3);
INSERT INTO `self_node` VALUES (9, add, 单元添加操作, 1, 操作动作, 0, 5, 3);

self_access表:self_node与self_role的关系表(重点分析好这个表

CREATE TABLE `self_access` (
  `role_id` smallint(6) unsigned NOT NULL,
  `node_id` smallint(6) unsigned NOT NULL,
  `level` tinyint(1) NOT NULL,
  `pid` varchar(50) DEFAULT NULL,
  KEY `groupId` (`role_id`),
  KEY `nodeId` (`node_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

INSERT INTO `self_access` VALUES (1, 1, 1, 0);
INSERT INTO `self_access` VALUES (2, 1, 1, 0);
INSERT INTO `self_access` VALUES (1, 2, 2, 1);
INSERT INTO `self_access` VALUES (2, 2, 2, 1);
INSERT INTO `self_access` VALUES (2, 3, 3, 2);
INSERT INTO `self_access` VALUES (1, 3, 3, 2);
INSERT INTO `self_access` VALUES (2, 4, 2, 1);
INSERT INTO `self_access` VALUES (1, 4, 2, 1);
INSERT INTO `self_access` VALUES (1, 6, 3, 4);
INSERT INTO `self_access` VALUES (2, 6, 3, 4);
INSERT INTO `self_access` VALUES (1, 7, 3, 4);

2、配置后台配置文件/Admin/Conf

‘USER_AUTH_ON‘=>true,//开启RBAC权限认证
‘USER_AUTH_TYPE‘=>1,//使用session进行标记
‘USER_AUTH_KEY‘=>‘authId‘,//设置session标记名称
‘ADMIN_AUTH_KEY‘=>‘administrator‘,//设置管理员用户标记
‘USER_AUTH_MODEL‘=>‘User‘,//验证用户的表模型
//‘AUTH_PWD_ENCODER‘=>‘md5‘,//用户认证密码加密方式
‘USER_AUTH_GATEWAY‘=>‘/Public/login‘,//默认的认证网关
‘NOT_AUTH_MODULE‘=>‘Public‘,//默认不需要认证的控制模块
‘REQUIRE_AUTH_MODULE‘=>‘‘,//默认需要认证的模块
‘NOT_AUTH_ACTION‘=>‘‘,//默认不需要认证的动作
‘REQUIRE_AUTH_ACTION‘=>‘‘,//默认需要认证的动作
‘GUEST_AUTH_ON‘=>false,//是否开启游客授权访问
‘GUEST_AUTH_ID‘=>0,//游客标记
    
‘RBAC_ROLE_TABLE‘=>‘self_role‘,
‘RBAC_USER_TABLE‘=>‘self_role_user‘,
‘RBAC_ACCESS_TABLE‘=>‘self_access‘,
‘RBAC_NODE_TABLE‘=>‘self_node‘,

3、公共控制器上进行验证:

class CommonAction extends Action{
    function _initialize(){
        header(‘Content-Type:text/html;charset=utf-8‘);
        //第一步:判断是否开启了认证  判断当前模块是否需要认证
        if(C(‘USER_AUTH_ON‘) && !in_array(MODULE_NAME,explode(‘,‘,C(‘NOT_AUTH_MODULE‘)))){
            //第二步:开启认证,导入RBAC类
            import(‘ORG.Util.RBAC‘);
            //判断不通过认证
            if(!RBAC::AccessDecision()){
                //第三步:当认证不通过是该如何处理
                //判断session中是否存放了用户标记
                if(!$_SESSION[C(‘USER_AUTH_KEY‘)]){
                    //用户没有登陆
                    $this->assign(‘jumpUrl‘,__APP__.‘/Public/login‘);
                    $this->error(‘对不起,您没有登陆,请登录‘);
                }//else //代表用户已经登陆
                
                //判断是否开启了游客登陆功能
                if(C(‘GUEST_AUTH_ON‘)){
                    //开启则跳转到游客页面
                }
                $this->error(‘对不起您没有操作权限‘);
            }//else 认证通过了
        }//else 没有开启认证或者当前模块不需要认证,则通过
    }
}

4、新建Public控制器PublicAction.class.php

class PublicAction extends Action{
    function login(){
        $this->display();
    }
    function verify(){
        import(‘ORG.Util.Image‘);
        Image::buildImageVerify();    
    }
    function checklogin(){
        //检查表单数据的有效性 用户名 密码 验证码必须填写
        if(empty($_POST[‘username‘])){
            $this->error(‘用户名必须填写‘);
        }
        if(empty($_POST[‘password‘])){
            $this->error(‘密码必须填写‘);
        }
        if(empty($_POST[‘verify‘])){
            $this->error(‘验证码必须填写‘);    
        }
        //整理需要用户验证的数据
        $map = array();
        $map[‘username‘] = $_POST[‘username‘];
        $map[‘active‘] = array(‘gt‘,0);
        if($_SESSION[‘verify‘] !== md5($_POST[‘verify‘])){
            $this->error(‘验证码输入错误‘);
        }
        
        //RBAC验证
        import(‘ORG.Util.RBAC‘);
        //提取用户数据
        $user = RBAC::authenticate($map);
        //判断是否能提取用户数据
        if(empty($user)){
            $this->error(‘用户不存在或者被禁用‘);
        }else{
            //如果数据提取成功,判断密码是否输入正确
            //注意:post中的密码要经过md5加密后再跟数据库中的密码进行比较
            if($user[‘password‘] != $_POST[‘password‘]){
                $this->error(‘用户密码输入错误‘);    
            }//else 密码验证通过
            
            //保存session的会话标识,用来后面判断用户已经登录的状态
            $_SESSION[C(‘USER_AUTH_KEY‘)] = $user[‘id‘];//把用户id存入session
            //存储后面需要用到的数据,如email 和登录时间等等
            $_SESSION[‘email‘] = $user[‘email‘];
            //超级管理身份验证
            if($user[‘admin‘] == ‘admin‘){
                $_SESSION[C(‘ADMIN_AUTH_KEY‘)] = true;    
            }
            
            //保存本用户的登录信息
            $u = M(‘User‘);
            $lastdate = date(‘Y-m-d H:i:s‘);
            $row[‘id‘] = $user[‘id‘];
            $row[‘last_login_date‘] = $lastdate;
            $u->save($row);
            //缓存访问权限
            RBAC::saveAccessList();
            //页面登录成功的跳转
            $this->assign(‘jumpUrl‘,__APP__.‘/Index/index‘);
            $this->success(‘登录成功‘);
        }
    }
    function logout(){
        //判断用户是否正在登录
        if(!empty($_SESSION[C(‘USER_AUTH_KEY‘)])){
            //正在登录中..
            unset($_SESSION[C(‘USER_AUTH_KEY‘)]);
            $_SESSION = array();
            session_destroy();
            $this->assign(‘jumpUrl‘,__URL__.‘/login‘);
            $this->success(‘登出成功‘);
        }else{
            //已经登出了
            $this->error(‘已经登出了‘);
        }
    }
}

5、建立success.html和login.html模板

success.html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>selfcms 系统信息提示</title>
</head>

<body>
<h1>{$msgTitle}</h1>
<h2>{$message}</h2>
<h3>
系统将在<font color="#FF0000">{$waitSecond}</font>秒后自动跳转,如果不想等待,请
<a href="{$jumpUrl}">点击这里</a>跳转
</h3>
</body>
</html>

login.html

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>login</title>
</head>

<body>
<form action="__URL__/checklogin" method="post">
用户名:<input type="text" name="username" /><br>
密码:<input type="password" name="password" /><br>
验证码:<input type="text" name="verify" /><img src="__URL__/verify" alt="验证码" /><br>
<input type="submit" value="登录" />
</form>
</body>
</html>

6、登出

<a href="__APP__/Public/logout">登出</a>

 

ThinkPHP RBAC权限管理机制

标签:

原文地址:http://www.cnblogs.com/longfeiPHP/p/4923044.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!