thinkPHP5框架auth权限控制类与用法示例
本文实例讲述了thinkPHP5框架auth权限控制类。分享给大家供大家参考,具体如下:
这个是比较简单的用法:
直接把类贴出来,这里我改了,我没有用uid,因为我建的表是admin表,所以代码里对应查询改成了aid
还有表名,我都去掉了前缀
//+----------------------------------------------------------------------
namespaceauth;
/**
*权限认证类
*功能特性:
*1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。
*$auth=newAuth();$auth->check('规则名称','用户id')
*2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and)
*$auth=newAuth();$auth->check('规则1,规则2','用户id','and')
*第三个参数为and时表示,用户需要同时具有规则1和规则2的权限。当第三个参数为or时,表示用户值需要具备其中一个条件即可。默认为or
*3,一个用户可以属于多个用户组(think_auth_group_access表定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group定义了用户组权限)
*
*4,支持规则表达式。
*在think_auth_rule表中定义一条规则时,如果type为1,condition字段就可以定义规则表达式。如定义{score}>5and{score}<100表示用户的分数在5-100之间时这条规则才会通过。
*/
//数据库
/*
------------------------------
--think_auth_rule,规则表,
--id:主键,name:规则唯一标识(就是常见的路由列表,如:admin/index/index),title:规则中文名称,例如添加商品status状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
------------------------------
DROPTABLEIFEXISTS`auth_rule`;
CREATETABLE`auth_rule`(
`id`mediumint(8)unsignedNOTNULLAUTO_INCREMENT,
`name`char(80)NOTNULLDEFAULT'',
`title`char(20)NOTNULLDEFAULT'',
`type`tinyint(1)NOTNULLDEFAULT'1',
`status`tinyint(1)NOTNULLDEFAULT'1',
`condition`char(100)NOTNULLDEFAULT'',#规则附件条件,满足附加条件的规则,才认为是有效的规则
PRIMARYKEY(`id`),
UNIQUEKEY`name`(`name`)
)ENGINE=MyISAMDEFAULTCHARSET=utf8;
------------------------------
--auth_group用户组表,
--id:主键,title:用户组中文名称,rules:用户组拥有的规则id,多个规则","隔开,status状态:为1正常,为0禁用
------------------------------
DROPTABLEIFEXISTS`auth_group`;
CREATETABLE`auth_group`(
`id`mediumint(8)unsignedNOTNULLAUTO_INCREMENT,
`title`char(100)NOTNULLDEFAULT'',
`status`tinyint(1)NOTNULLDEFAULT'1',
`rules`char(80)NOTNULLDEFAULT'',
PRIMARYKEY(`id`)
)ENGINE=MyISAMDEFAULTCHARSET=utf8;
------------------------------
--group_access用户组明细表
--uid:用户id,group_id:用户组id
------------------------------
DROPTABLEIFEXISTS`group_access`;
CREATETABLE`group_access`(
`uid`mediumint(8)unsignedNOTNULL,
`group_id`mediumint(8)unsignedNOTNULL,
UNIQUEKEY`uid_group_id`(`uid`,`group_id`),
KEY`uid`(`uid`),
KEY`group_id`(`group_id`)
)ENGINE=MyISAMDEFAULTCHARSET=utf8;
*/
classAuth{
//默认配置
protected$_config=array(
'auth_on'=>true,//认证开关
'auth_type'=>1,//认证方式,1为实时认证;2为登录认证。
'auth_group'=>'auth_group',//用户组数据表名
'auth_group_access'=>'group_access',//用户-用户组关系表
'auth_rule'=>'auth_rule',//权限规则表
'auth_user'=>'admin'//用户信息表
);
publicfunction__construct(){
if(config('auth_config')){
//可设置配置项auth_config,此配置项为数组。
$this->_config=array_merge($this->_config,config('auth_config'));
}
}
/**
*检查权限
*@paramnamestring|array需要验证的规则列表,支持逗号分隔的权限规则或索引数组
*@paramuidint认证用户的id
*@paramstringmode执行check的模式
*@paramrelationstring如果为'or'表示满足任一条规则即通过验证;如果为'and'则表示需满足所有规则才能通过验证
*@returnboolean通过验证返回true;失败返回false
*/
publicfunctioncheck($name,$uid,$type=1,$mode='url',$relation='or'){
if(!$this->_config['auth_on'])
returntrue;
$authList=$this->getAuthList($uid,$type);//获取用户需要验证的所有有效规则列表
if(is_string($name)){
$name=strtolower($name);
if(strpos($name,',')!==false){
$name=explode(',',$name);
}else{
$name=array($name);
}
}
$list=array();//保存验证通过的规则名
if($mode=='url'){
$REQUEST=unserialize(strtolower(serialize($_REQUEST)));
}
foreach($authListas$auth){
$query=preg_replace('/^.+\?/U','',$auth);
if($mode=='url'&&$query!=$auth){
parse_str($query,$param);//解析规则中的param
$intersect=array_intersect_assoc($REQUEST,$param);
$auth=preg_replace('/\?.*$/U','',$auth);
if(in_array($auth,$name)&&$intersect==$param){//如果节点相符且url参数满足
$list[]=$auth;
}
}elseif(in_array($auth,$name)){
$list[]=$auth;
}
}
if($relation=='or'and!empty($list)){
returntrue;
}
$diff=array_diff($name,$list);
if($relation=='and'andempty($diff)){
returntrue;
}
returnfalse;
}
/**
*根据用户id获取用户组,返回值为数组
*@paramuidint用户id
*@returnarray用户所属的用户组array(
*array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
*...)
*/
publicfunctiongetGroups($uid){
static$groups=array();
if(isset($groups[$uid]))
return$groups[$uid];
$user_groups=\think\Db::name($this->_config['auth_group_access'])
->alias('a')
->join($this->_config['auth_group']."g","g.id=a.group_id")
->where("a.aid='$uid'andg.status='1'")
->field('aid,group_id,title,rules')->select();
$groups[$uid]=$user_groups?$user_groups:array();
return$groups[$uid];
}
/**
*获得权限列表
*@paraminteger$uid用户id
*@paraminteger$type
*/
protectedfunctiongetAuthList($uid,$type){
static$_authList=array();//保存用户验证通过的权限列表
$t=implode(',',(array)$type);
if(isset($_authList[$uid.$t])){
return$_authList[$uid.$t];
}
if($this->_config['auth_type']==2&&isset($_SESSION['_auth_list_'.$uid.$t])){
return$_SESSION['_auth_list_'.$uid.$t];
}
//读取用户所属用户组
$groups=$this->getGroups($uid);
$ids=array();//保存用户所属用户组设置的所有权限规则id
foreach($groupsas$g){
$ids=array_merge($ids,explode(',',trim($g['rules'],',')));
}
$ids=array_unique($ids);
if(empty($ids)){
$_authList[$uid.$t]=array();
returnarray();
}
$map=array(
'id'=>array('in',$ids),
'type'=>$type,
'status'=>1,
);
//读取用户组所有权限规则
$rules=\think\Db::name($this->_config['auth_rule'])->where($map)->field('condition,name')->select();
//循环规则,判断结果。
$authList=array();//
foreach($rulesas$rule){
if(!empty($rule['condition'])){//根据condition进行验证
$user=$this->getUserInfo($uid);//获取用户信息,一维数组
$command=preg_replace('/\{(\w*?)\}/','$user[\'\\1\']',$rule['condition']);
//dump($command);//debug
@(eval('$condition=('.$command.');'));
if($condition){
$authList[]=strtolower($rule['name']);
}
}else{
//只要存在就记录
$authList[]=strtolower($rule['name']);
}
}
$_authList[$uid.$t]=$authList;
if($this->_config['auth_type']==2){
//规则列表结果保存到session
$_SESSION['_auth_list_'.$uid.$t]=$authList;
}
returnarray_unique($authList);
}
/**
*获得用户资料,根据自己的情况读取数据库
*/
protectedfunctiongetUserInfo($uid){
static$userinfo=array();
if(!isset($userinfo[$uid])){
$userinfo[$uid]=\think\Db::name($this->_config['auth_user'])->where(array('aid'=>$uid))->find();
}
return$userinfo[$uid];
}
}
Auth.php放在extend下面的auth目录里,命名空间为auth
然后在使用的控制器中使用构造方法,或者继承一个使用了构造方法的控制器,构造方法如下:
publicfunction_initialize()
{
$aid=1;
$auth=new\auth\Auth();
$request=Request::instance();
$au=$auth->check($request->module().'/'.$request->controller().'/'.$request->action(),$aid);
if(!$au){//第一个参数是规则名称,第二个参数是用户UID
/*returnarray('status'=>'error','msg'=>'有权限!');*/
$this->error('你没有权限');
}
}
上面的$aid应该是用户登录以后获取的,正常情况下应该是session()获取的用户id
相关业务逻辑可以自行判断,剩下的就是添加全县,用户组添加啊,等等系列增删改查了。
更多关于thinkPHP相关内容感兴趣的读者可查看本站专题:《ThinkPHP入门教程》、《thinkPHP模板操作技巧总结》、《ThinkPHP常用方法总结》、《codeigniter入门教程》、《CI(CodeIgniter)框架进阶教程》、《ZendFrameWork框架入门教程》及《PHP模板技术总结》。
希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。