管理权限的优势就是它很安全,不会被一些小BUG影响,导致这个网站或者这个软件混乱  ,生活里遇见问题个人比较喜欢用三W的方式去解决也就是'who what how',

  首先是who:

        权限管理规则

  其次:what

          权限管理里面我们需要明白管理权限的规则是什么:这个规则就是当前用户当前页面的当前地址

          实现的原理是什么:原理很简单,就是我当前的规则在我的规则表里面是否存在

  最后:how

          怎么做可以分为两步:

                one  :  建立四个表,因为我们做什么得从实际出发,分析这个这个表里面需要什么

                第一个表:这个表里储存当前的角色,因为我们后期所做的所有功能都是基于这个角色, 这个任意表满足三范式即可

         权限管理的规则

              第二个表:授权的规则表

            权限管理的规则

               第三个表:会员和授权表的管理变

                权限管理的规则

              第四个表:权限表,表里权限可以根据你需要的权限进行添加

权限管理的规则

              two :  建好表以后我们就需要实现这个功能

            /**
 * 权限认证类
 *
 * 功能特性:
 * 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。
 *      $auth=new Auth();  $auth->check('规则名称','用户id')
 * 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and)
 *      $auth=new Auth();  $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}>5  and {score}<100  表示用户的分数在5-100之间时这条规则才会通过。
 *

 */

              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_admin'//用户信息表
);


public function __construct() {
//先判断是否有配置文件的权限
        if (config('AUTH_CONFIG')){
            //可设置配置项 AUTH_CONFIG, 此配置项为数组。
            $this->_config = array_merge($this->_config, config('AUTH_CONFIG'));
        }
    }

//获得权限$name 可以是字符串或数组或逗号分割, uid为 认证的用户id, $or 是否为or关系,为true是, name为数组,只要数组中有一个条件通过则通过,如果为false需要全部条件通过。
    /**
* @ $name - 当前页面的地址(对应规则表的Name字段)
* @ $uid - 当前用户的ID
* @ $relation - 规则表达式:默认'or',判断$relation是否为空,不为空,就把$relation当成查询条件
*/
// $name = 'index/index/index,index/admin/save'
    public function check($name, $uid, $relation='or') {
    //1:判断是否开启权限验证
    //功能作用
if (!$this->_config['AUTH_ON']){
return true;
}
//who开始
// 判断当前登陆用户拥有的权限 也就是地址
$name = strtolower($name);
//获取当前用户的所有权限
//2.获取当前用户组 所具有的全部权限 
//$authList:
$authList = $this->getAuthList($uid);
if (is_string($name)) {
            if (strpos($name, ',') !== false) {
                $name = explode(',', $name);
            } else {
                $name = array($name);
            }
        }
//判断两个数组是否有相同的部分
//循环的去和数据库里面的节点表进行比较
//3.判断我需要认证的页面的权限是否在所有权限里面
$list = array(); //有权限的name
        foreach ($authList as $val) {
            if (in_array($val, $name))
                $list[] = $val;
        }
//4.判断第三步产生的一个或者多个权限的认证方式
if ($relation=='or' and !empty($list)) {
            return true;
        }
//获取需要验证的路径和当前用户又具有的所有权限中的路径
$diff = array_diff($name, $list);
//如果获取的数据库里的路径和当前的路径相等 则说明具有权限
        if ($relation=='and' and empty($diff)) {
            return true;
        }
return false;
}


/**
* 获取用户的权限列表
*/
public function getAuthList($uid){
//定义一个空的静态的数组,可以像session一样保存数据
static $_authList = array();
//如果已经查过就直接返回查过的数据,否则就联表查
if (isset($_authList[$uid])) {
            return $_authList[$uid];
        }
//主要是针对2为登录认证的情况
if(isset($_SESSION['_AUTH_LIST_'.$uid])){
            return $_SESSION['_AUTH_LIST_'.$uid];
        }
//查用户所在组
$groups = $this->getGroups($uid);
//把roles字段里面的“1,2,2,2,2,3,4...”变成数组
$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();
        } 
//通过$ids查rule表
$rules = DB::table($this->_config['AUTH_RULE'])->select(['id'=>array('in',$ids),'status'=>1]);
//循环规则,判断结果。
        $authList = array();
        foreach ($rules as $r) {
            if (!empty($r['condition'])) {
                //条件验证
                $user = $this->getUserInfo($uid);
//把rule表里面的condition字段里面的{id}>2中{id}替换成$user['id']
                $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $r['condition']);
//使用eval方来执行字符串语句,将结果保存到$condition里面
                @(eval('$condition=(' . $command . ');'));
//如果$condition==true,就满足条件
                if ($condition) {
                    $authList[] = strtolower($r['name']);
                }
            } else {
                //存在就通过
                $authList[] = strtolower($r['name']);
            }
        }
//将得到的结果保存到静态数组里面
$_authList[$uid] = $authList;
//如果验证方式是登录验证,就是保存到session里面
        if($this->_config['AUTH_TYPE']==2){
            //session结果
            $_SESSION['_AUTH_LIST_'.$uid]=$authList;
        }
        return $authList;
}

          

相关文章: