基于Auth认证类的权限分配及menu菜单过滤

http://www.thinkphp.cn/topic/49737.html

另外一个参考网址:http://www.thinkphp.cn/extend/873.html

声明:本人菜鸟一只,仅以此文献给有和我同样需求的TPer,向高手及前辈致敬!
----------------------------------------------------------------------------
需求说明:我在一个实际项目中需要做到,不同的角色的用户登录以后显示不同的菜单(左侧),以及对应不同的crud权限。
-----------------------------------------------------------------------------
ghzz789大神, 在“Auth权限认证暴力来袭,有图有码有种子,绝对暴力!”(链接地址:http://www.thinkphp.cn/code/714.html)点击下载:https://download.csdn.net/download/jshyzx1999/12284171很好地说明了基于auth的认证类,我下载了他的demo,仔细看过了代码,权限分配的确很清晰,不过好像做到过滤菜单(比方说用户张三仅仅具备A、B菜单的权限A、B、C三个菜单仍旧会显示给他,从某种程度上影响了用户体验。)
---------------------------------------------------------------
白俊遥大神 ,在其博客中也很好的阐述了 基于Auth的权限认证及菜单的分配,我仔细看过其代码以后发现它需要额外的做一个菜单分配的操作。
-----------------------------------------------------------------
luofei614 大神,在“比RBAC更好的权限认证方式(Auth类认证)”(链接地址:http://www.thinkphp.cn/topic/4029.html)一文中同样阐释了基于auth的权限分配,遗憾的是没有提到如何基于权限显示不同的菜单。
-----------------------------------------------------
受到上述大神的启发,稍微改造了一下 auth类,基本实现了我需要的功能。代码如下:
1. 用到的类,TP自带的auth.class.php
2.按照auth.class.php自带的注释,建立必须的数据库:


-- ----------------------------
-- think_auth_rule,规则表,
-- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_rule`;
CREATE TABLE `think_auth_rule` ( 
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
`name` char(80) NOT NULL DEFAULT '', 
`title` char(20) NOT NULL DEFAULT '', 
`type` tinyint(1) NOT NULL DEFAULT '1', 
`status` tinyint(1) NOT NULL DEFAULT '1', 
`condition` char(100) NOT NULL DEFAULT '', # 规则附件条件,满足附加条件的规则,才认为是有效的规则
PRIMARY KEY (`id`), 
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- think_auth_group 用户组表, 
-- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_group`;
CREATE TABLE `think_auth_group` ( 
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
`title` char(100) NOT NULL DEFAULT '', 
`status` tinyint(1) NOT NULL DEFAULT '1', 
`rules` char(80) NOT NULL DEFAULT '', 
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- ----------------------------
-- think_auth_group_access 用户组明细表
-- uid:用户id,group_id:用户组id
-- ----------------------------
DROP TABLE IF EXISTS `think_auth_group_access`;
CREATE TABLE `think_auth_group_access` ( 
`uid` mediumint(8) unsigned NOT NULL, 
`group_id` mediumint(8) unsigned NOT NULL, 
UNIQUE KEY `uid_group_id` (`uid`,`group_id`), 
KEY `uid` (`uid`), 
KEY `group_id` (`group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

3.添加字段:在think_auth_rule 表中添加字段 pid及ismenu ,用于菜单生成、及是否显示。
4.生成菜单及根据不同权限过滤菜单:

//返回所有菜单分类
function unlimitedForLayer ($cate, $name = 'child', $pid = 0) {
    $arr = array();
    foreach ($cate as $v) {
        if ($v['pid'] == $pid) {
            $v[$name] = unlimitedForLayer($cate, $name, $v['id']);
            $arr[] = $v;
        }
    }
    return $arr;
}
function getAllMenu(){    
    $model = M('auth_rule');  //从数据库读取菜单
    $cate = $model->where('ismenu = 1')->order('id asc')->select();     //读取用作菜单显示的
    //var_dump($cate);die;
    $menu=unlimitedForLayer($cate);
    //var_dump($model->_sql());
    //var_dump($menu);die;
    return $menu;
}
function getMenuList($auth_id){
    //根据角色权限过滤菜单
    $menu_list = getAllMenu();   //获取所有菜单
    //print_r($menu_list);die;
    if($auth_id!='1'){   //超级管理员加载所有菜单
        $auth = new \Think\Auth();            
        
        //$authList = $auth->getGroups($auth_id);      //根据用户id获取用户组,返回值为数组
        //$role_right = $authList[0]['rules'];         //得到有效权限id
        //var_dump($role_right);die;
        //$role_right = explode(',', $role_right);        //形成数组        
        
        $authList = $auth->getAuthList($auth_id,1); //获取用户需要验证的所有有效规则列表
        $map['name']=array('in',$authList);        
        $role_right = M('auth_rule')->where($map)->getField('id',true);    
        foreach($menu_list as $k=>$v){
            foreach ($v['child'] as $kk=>$vv){
                    if(!in_array($vv['id'], $role_right)){    //判断数组是否在菜单表里面
                        unset($menu_list[$k]['child'][$kk]);//过滤菜单
                    }
            }
        }        
        
    }
    return $menu_list;
}

5.基于节点的权限分配。

   //_initialize自动运行方法,在每个方法前,系统会首先运动这个方法
    public function _initialize()
    {
        
         $ctl = CONTROLLER_NAME;
        $act = ACTION_NAME;
        $auth_id = session('auth_id');  //接受session
        
        
        if($auth_id==null){            
            //$this->redirect("/Home/index");
            $this->error('请先登录以后再操作!',U('/Home/index'));
        }        
        
        //无需验证的操作
        $uneed_check = array('login','logout','vertifyHandle','vertify','imageUp','upload','login_task');
        $uneed_check_cont = array('Index','Main');
        
        if(in_array($ctl,$uneed_check_cont) || $auth_id == '1'){
            //后台首页控制器无需验证,超级管理员无需验证
            return true;
        }elseif(strpos('ajax',$act) || in_array($act,$uneed_check)){
            //所有ajax请求不需要验证权限
            return true;
        }else{
            $auth = new \Think\Auth();    
            if(!$auth->check(MODULE_NAME.'/'.CONTROLLER_NAME.'/'.ACTION_NAME, $auth_id)){
                $this->error('没有权限');
            }            
        }
         
    }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值