在基于结点验证权限时,不想将有权限的结点都录入规则表,感觉很麻烦!
我的思想是:
1、规则表中没有规则的话,表示用户拥有所有权限。
2、所谓的权限是因为有规则的限制才产生了权限
3、Action的规则高于Module的规则,Module的规则高于Group的规则
4、根据这Goup、Module、Action3条规则来控制用户访问,因此不必将所有结点都写入规则表。
5、未登录用户赋于uid值0,可以通过0获取该未登录用户的规则控制
举个例子,我在规则表中定义几条规则,可以实现用户的权限控制,但还不能确认是否有问题:
1、针对后台分组Admin,默认用户有Admin访问限权,因为规则表中没有规则!
2、因此必须定义Admin分组没有权限,规则表中定义tof字段为0。
3、此时,用户没有任何访问权限,连登录都不行,因此需要定义用户的登录规则,User模块也定义tof字段为0,若定义为1表示User模块下的所有操作都有权限,肯定不行。
4、定义login的tof字段为1,表示拥有login操作权限
5、定义的这3个字段必须有从属关系,数据表中pid字段标志
权限验证:用户有login操作权限,虽然能够登录却并没有进入后台主界面的权限,以上只是未登录用户的控制。
6、以上描述可以作为系统默认控制
对于登录通过的用户再进行权限判断。
class Auth{
//默认配置
protected $_config = array(
'AUTH_ON' => true, //认证开关
'AUTH_TYPE' => 1, // 认证方式,1为时时认证;2为登录认证。
'AUTH_GROUP' => 'think_auth_group', //用户组数据表名
'AUTH_GROUP_ACCESS' => 'think_auth_group_access', //用户组明细表
'AUTH_RULE' => 'think_auth_rule', //权限规则表
'AUTH_USER' => 'think_members'//用户信息表
);
public function __construct() {
if (C('AUTH_CONFIG')) {
//可设置配置项 AUTH_CONFIG, 此配置项为数组。
$this->_config = array_merge($this->_config, C('AUTH_CONFIG'));
}
}
public function check($name, $authList) {
$nameArr = explode('.', strtolower($name));
foreach($authList['name'] as $key => $value){
if($authList['isnode'][$key] == 1 && $authList['pid'][$key] == 0 && $nameArr[0] == strtolower($value)){
$g_priv = $authList['tof'][$key];
$g_id = $authList['id'][$key];
break;
}
}
if(!isset($g_priv))
return true;
foreach($authList['name'] as $key => $value){
if($authList['isnode'][$key] == 1 && $authList['pid'][$key] == $g_id && $nameArr[1] == strtolower($value)){
$m_priv = $authList['tof'][$key];
$m_id = $authList['id'][$key];
break;
}
}
if(!isset($m_priv) && $g_priv == 1)
return true;
foreach($authList['name'] as $key => $value){
if($authList['isnode'][$key] == 1 && $authList['pid'][$key] == $m_id && $nameArr[2] == strtolower($value)){
$a_priv = $authList['tof'][$key];
break;
}
}
if(!isset($a_priv) && $m_priv == 1)
return true;
else if($a_priv == 1)
return true;
return false;
}
//获得用户组,外部也可以调用
public function getGroups($uid) {
$uid = empty($uid) ? 0 : $uid;
static $groups = array();
if (isset($groups[$uid]))
return $groups[$uid];
if($uid === 0){
$user_groups = M()->table($this->_config['AUTH_GROUP'] . ' g')->where('g.id = 1')->select();
if(empty($user_groups))
die('系统游客默认权限设置错误!');
}
else{
$user_groups_def = M()->table($this->_config['AUTH_GROUP'] . ' g')->where('g.id = 2')->select();
if(empty($user_groups_def))
die('系统默认权限设置错误!');
$user_groups = M()->table($this->_config['AUTH_GROUP_ACCESS'] . ' a')->where("a.uid='$uid' and g.status='1'")->join($this->_config['AUTH_GROUP']." g on a.gid=g.id")->select();
if(empty($user_groups))
$user_groups = array();
$user_groups = array_merge($user_groups_def, $user_groups);
}
$groups[$uid]= $user_groups;
return $groups[$uid];
}
//获得权限列表
public function getAuthList($uid, $isnode) {
static $_authList = array();
if (isset($_authList[$uid])) {
return $_authList[$uid];
}
//读取用户所属用户组
$groups = $this->getGroups($uid);
$ids = array();
foreach ($groups as $g) {
$ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
}
$ids = array_unique($ids);
if (empty($ids)) {
$_authList[$uid] = array();
return array();
}
//读取用户组所有权限规则
$map=array(
'id'=>array('in',$ids),
'status'=>1
);
$rules = M()->table($this->_config['AUTH_RULE'])->where($map)->order('tof desc')->select();
//循环规则,判断结果。
$authList = array();
foreach ($rules as $r) {
//存在就通过
$authList['name'][] = $r['name'];
$authList['id'][] = $r['id'];
$authList['pid'][] = $r['pid'];
$authList['tof'][] = $r['tof'];
$authList['isnode'][] = $r['isnode'];
}
return $authList;
}
//获得用户资料,根据自己的情况读取数据库
protected function getUserInfo($uid) {
static $userinfo=array();
if(!isset($userinfo[$uid])){
$userinfo[$uid]=M()->table($this->_config['AUTH_USER'])->find($uid);
}
return $userinfo[$uid];
}
}只更改了一个auth_rule表
个人已经成功实现这样的权限验证,感觉非常方便!但不知是否有问题?
最佳答案