注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

php开发lamp

《西安--木木》-经历丰富了生活。 架构师QQ群: 246695517

 
 
 

日志

 
 

RBAC--基于角色的访问控制  

2013-02-11 06:26:45|  分类: php基础 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

tp教程:

http://wolf123.blog.163.com/blog/#m=0&t=1&c=fks_084066081083082066084085080095085081084067081082084074092

 

1.查询当前用户有权访问的所有节点,(项目下的--模块--方法)组成。

2.检查用户是否登录(登录调用3,否则跳转)

3.将用户有权访问的所有节点以array形式保存到session(数组为三维数组array('项目'=>array('模块'=>array(方法=>'update'))))

3.检查用户是否有权限访问当前的模块--方法。(true则访问,false则不能访问)

用户登录成功--->检查当前操作的方法是否存在于用户有权访问的节数组中

4.检查当前的操作(模块--方法)是否需要认证  (一种是需要认证的。另一种是不需要认证。)

 

检查当前登录用户是否有操作当前模块--方法 _initialize()。

将initialize()方法放到action 基类的__constuct()方法中执行。

所有的控制器类都继承自action类。

--------------------------------------------

每次只能调用action下的一个方法,才能保证权限调用的合理性。

调用第二次方法,__constuct()不在执行。

构造函数是类中的一个特殊函数,当使用 new 操作符创建一个类的实例时,构造函数将会自动调用。当函数与类同名时,这个函数将成为构造函数。如果一个类没有构造函数,则调用基类的构造函数,如果有的话。

------------------


 

  1. 用户表(包含三个字段用户编号,用户名和用户密码)
  2. 用户组表(用户组编号和名字)
  3. 用户与组的对应关系表(组编号和用户编号)
  4. 节点表(节点编号,名字,注释,父路径编号,等级)(注:这个表很容易将人搞晕)
  5. 权限表(组编号,节点编号,父路径编号,等级)

‘RBAC_ROLE_TABLE’=>’role’, //用户角色表
‘RBAC_USER_TABLE’=>’admin’,//管理员账户表
‘RBAC_ACCESS_TABLE’=>’role_access’,//角色权限表
‘RBAC_NODE_TABLE’=>’role_node’,//网站操作节点

access表的level有三个可取得值:(1,2,3)1、项目app;2、项目module类;3、action操作;

RBAC::authenticate();//获取RBAC_USER_TABLE中管理员的账户密码,id进行登录验证

RBAC::saveAccessList//用于检测用户权限的方法(action节点),并保存到Session中

RBAC::getRecordAccessList//取得模块的所属记录访问权限列表(module) 返回有权限的记录ID数组


 以下是Tp的rbac的数据表

CREATE TABLE IF NOT EXISTS `joys_access` (
  `role_id` smallint(5) unsigned NOT NULL,
  `node_id` smallint(5) unsigned NOT NULL,
  `level` tinyint(4) NOT NULL,
  `pid` smallint(6) NOT NULL,
  KEY `role_id` (`role_id`,`node_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 role_id  node_id  level  pid  
1 1 1 0
1 2 2 1
1 9 3 2
1 7 3 2
2 7 3 2
1 5 2 1
1 11 3 5
------------------------------------------
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;
id  name  title  status  remark  sort  pid  level   
 1 Admin 后台管理 1 后台项目 0 0 1    
 2 Section 单元管理 1 控制器 1 1 2   
 3 Category 分类管理 1 控制器 2 1 2   
 4 Article 文章管理 1 控制器 3 1 2   
 5 Index 后台默认 1 控制器 0 1 2   
 6 Public 公共管理 1 控制器 0 1 2   
 7 index 单元列表 1 动作 0 2 3
----------------------------------------
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 ;
 id  name  pid  status  remark  
1 超级管理员 0 1 超级管理员分组
2 普通管理员 0 1 普通管理员分组
3 注册用户 0 1 注册用户分组
--------------------------------------------
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;
role_id  user_id  
1 1
1 1
1 1
1 1
1 1
1 1
---------------------------------
 /**
     +----------------------------------------------------------
     * 取得当前认证号的所有权限列表
     +----------------------------------------------------------
     * @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;
    }
 
// 读取模块所属的记录访问权限
 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;
 }
  评论这张
 
阅读(1505)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017