精华内容
下载资源
问答
  • 基于开发框架ThinkPHP5写的权限控制网站demo。规则表(think_auth_rule) 用户组表(think_auth_group) 用户组明显表(think_auth_group_access) 我们在规则表中定义权限规则, 在用户组表中定义每个用户组有哪些...
  • tp5Auth权限实现

    2019-10-16 10:36:21
    下面本人为大家讲解一下如何实现auth权限, 第一步,新建Auth.php,复制下面的代码,把注释中的表都创建一下。把文件放到extend新建文件夹org放进去即可, <?php // +------------------------------------------...

    下面本人为大家讲解一下如何实现auth权限,
    第一步,新建Auth.php,复制下面的代码,把注释中的表都创建一下。把文件放到extend新建文件夹org放进去即可,
    <?php 
    // +----------------------------------------------------------------------
    // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
    // +----------------------------------------------------------------------
    // | Copyright (c) 2011 http://thinkphp.cn All rights reserved.
    // +----------------------------------------------------------------------
    // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
    // +----------------------------------------------------------------------
    // | Author: luofei614 <weibo.com/luofei614>
    // +----------------------------------------------------------------------
    // | 修改者: anuo (本权限类在原3.2.3的基础上修改过来的)
    // +----------------------------------------------------------------------
    use think\Db;
    use think\Config;
    use think\Session;
    use think\Request;
    use think\Loader; 
     
    /**
     * 权限认证类
     * 功能特性:
     * 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之间时这条规则才会通过。
     */
    //数据库
    /*
    -- ----------------------------
    -- 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;
     */
     
    class Auth
    {
        /**
         * @var object 对象实例
         */
        protected static $instance;
        /**
         * 当前请求实例
         * @var Request
         */
        protected $request;
     
        //默认配置
        protected $config = [
            'auth_on'           => 1, // 权限开关
            'auth_type'         => 1, // 认证方式,1为实时认证;2为登录认证。
            'auth_group'        => 'auth_group', // 用户组数据表名
            'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
            'auth_rule'         => 'auth_rule', // 权限规则表
            'auth_user'         => 'member', // 用户信息表
        ];
     
        /**
         * 类架构函数
         * Auth constructor.
         */
        public function __construct()
        {
            //可设置配置项 auth, 此配置项为数组。
            if ($auth = Config::get('auth')) {
                $this->config = array_merge($this->config, $auth);
            }
            // 初始化request
            $this->request = Request::instance();
        }
     
        /**
         * 初始化
         * @access public
         * @param array $options 参数
         * @return \think\Request
         */
        public static function instance($options = [])
        {
            if (is_null(self::$instance)) {
                self::$instance = new static($options);
            }
     
            return self::$instance;
        }
     
        /**
         * 检查权限
         * @param        $name     string|array  需要验证的规则列表,支持逗号分隔的权限规则或索引数组
         * @param        $uid      int           认证用户的id
         * @param int    $type     认证类型
         * @param string $mode     执行check的模式
         * @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
         * @return bool               通过验证返回true;失败返回false
         */
        public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or')
        {
            if (!$this->config['auth_on']) {
                return true;
            }
            // 获取用户需要验证的所有有效规则列表
            $authList = $this->getAuthList($uid, $type);
            if (is_string($name)) {
                $name = strtolower($name);
                if (strpos($name, ',') !== false) {
                    $name = explode(',', $name);
                } else {
                    $name = [$name];
                }
            }
            $list = []; //保存验证通过的规则名
            if ('url' == $mode) {
                $REQUEST = unserialize(strtolower(serialize($this->request->param())));
            }
            foreach ($authList as $auth) {
                $query = preg_replace('/^.+\?/U', '', $auth);
                if ('url' == $mode && $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;
                    }
                } else {
                    if (in_array($auth, $name)) {
                        $list[] = $auth;
                    }
                }
            }
            if ('or' == $relation && !empty($list)) {
                return true;
            }
            $diff = array_diff($name, $list);
            if ('and' == $relation && empty($diff)) {
                return true;
            }
     
            return false;
        }
     
        /**
         * 根据用户id获取用户组,返回值为数组
         * @param  $uid int     用户id
         * @return array       用户所属的用户组 array(
         *              array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
         *              ...)
         */
        public function getGroups($uid)
        {
            static $groups = [];
            if (isset($groups[$uid])) {
                return $groups[$uid];
            }
            // 转换表名
            $auth_group_access = Loader::parseName($this->config['auth_group_access'], 1);
            $auth_group        = Loader::parseName($this->config['auth_group'], 1);
            // 执行查询
            $user_groups  = Db::view($auth_group_access, 'uid,group_id')
                ->view($auth_group, 'title,rules', "{$auth_group_access}.group_id={$auth_group}.id", 'LEFT')
                ->where("{$auth_group_access}.uid='{$uid}' and {$auth_group}.status='1'")
                ->select();
            $groups[$uid] = $user_groups ?: [];
     
            return $groups[$uid];
        }
     
        /**
         * 获得权限列表
         * @param integer $uid 用户id
         * @param integer $type
         * @return array
         */
        protected function getAuthList($uid, $type)
        {
            static $_authList = []; //保存用户验证通过的权限列表
            $t = implode(',', (array)$type);
            if (isset($_authList[$uid . $t])) {
                return $_authList[$uid . $t];
            }
            if (2 == $this->config['auth_type'] && Session::has('_auth_list_' . $uid . $t)) {
                return Session::get('_auth_list_' . $uid . $t);
            }
            //读取用户所属用户组
            $groups = $this->getGroups($uid);
            $ids    = []; //保存用户所属用户组设置的所有权限规则id
            foreach ($groups as $g) {
                $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
            }
            $ids = array_unique($ids);
            if (empty($ids)) {
                $_authList[$uid . $t] = [];
     
                return [];
            }
            $map = [
                'id'   => ['in', $ids],
                'type' => $type
            ];
            //读取用户组所有权限规则
            $rules = Db::name($this->config['auth_rule'])->where($map)->field('condition,name')->select();
            //循环规则,判断结果。
            $authList = []; //
            foreach ($rules as $rule) {
                if (!empty($rule['condition'])) {
                    //根据condition进行验证
                    $user    = $this->getUserInfo($uid); //获取用户信息,一维数组
                    $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
                    @(eval('$condition=(' . $command . ');'));
                    if ($condition) {
                        $authList[] = strtolower($rule['name']);
                    }
                } else {
                    //只要存在就记录
                    $authList[] = strtolower($rule['name']);
                }
            }
            $_authList[$uid . $t] = $authList;
            if (2 == $this->config['auth_type']) {
                //规则列表结果保存到session
                Session::set('_auth_list_' . $uid . $t, $authList);
            }
     
            return array_unique($authList);
        }
     
        /**
         * 获得用户资料
         * @param $uid
         * @return mixed
         */
        protected function getUserInfo($uid)
        {
            static $user_info = [];
     
            $user = Db::name($this->config['auth_user']);
            // 获取用户表主键
            $_pk = is_string($user->getPk()) ? $user->getPk() : 'uid';
            if (!isset($user_info[$uid])) {
                $user_info[$uid] = $user->where($_pk, $uid)->find();
            }
     
            return $user_info[$uid];
        }
    }
    第二步 新建控制器,其它的权限添加就不多说了,下面是验证最终结果
    <?php
    namespace app\admin\controller;
    use \think\Controller;
    use think\Loader;
    class Base extends Controller
    {
        protected $current_action;
        public function _initialize()
        {
            Loader::import("org/Auth", EXTEND_PATH);
            $auth=new \Auth();
            $this->current_action = request()->module().'/'.request()->controller().'/'.lcfirst(request()->action());
            $result = $auth->check($this->current_action,session('user_id'));
            if($result){
                echo "权限验证成功";
            }
        }
    }
    欢迎加入php技术交流,资源分享群

    加群可获取下面视频一套,有效期至2018/1/30


    版权声明:本文为CSDN博主「qq_33257081」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_33257081/article/details/79137190

    展开全文
  • tp5 auth权限设置

    2018-05-23 15:02:00
    案例:把所需要的auth类放在一个公共的地方引用,我这里就只是放在了与application同级的extend里面的org所以我在公共控制器里面实例为use \org\Auth; 然后我再公共控制器里面写 class Common extends Base{//任何...

    案例:把所需要的auth类放在一个公共的地方引用,我这里就只是放在了与application同级的extend里面的org所以我在公共控制器里面实例为use \org\Auth; 然后我再公共控制器里面写

    class Common extends Base
    {
    //任何操作加载的时候,会调用此函数
    function _initialize(){
    if(!Session::get(“uid”)){
    $this->error(“请先登录!”,”admin/login/index”);
    }
    $AUTH=new \org\Auth();
    $mod=request()->module();
    $con=request()->controller();
    $act=request()->action();
    $str=$mod.’/’.$con.’/’.$act; //把模块、控制器和方法转换成一个字符串
    //echo $str;
    if(!$AUTH->check($str,Session::get(“uid”))){
    $this->error(“您没有该操作的权限!”,”admin/index/showError”);
    }
    }
    }

    在各个控制器里面都继承这个common控制器。

     

    想要实现权限管理功能,还需要建对应的数据表

    //数据库
    /*
    — —————————-
    — 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;
    */

    这里面的字段可能需要修改样式

    然后在后台创建操作页面进行操作。

    转载于:https://www.cnblogs.com/xin521/p/9076968.html

    展开全文
  • tp5 Auth权限认证方法与步骤

    千次阅读 2018-11-06 17:58:29
    一、概述 RBAC是按节点进行认证的,如果要控制比节点更细的权限就有点困难了,比如页面上面的操作按钮, 我想判断用户...下面介绍 Auth权限认证, 它几乎是全能的, 除了能进行节点认证, 上面说的RABC很难认证的两...

    一、概述

    RBAC是按节点进行认证的,如果要控制比节点更细的权限就有点困难了,比如页面上面的操作按钮, 我想判断用户权限来显示这个按钮, 如果没有权限就不会显示这个按钮; 再比如我想按积分进行权限认证, 积分在0-100时能干什么, 在101-200时能干什么。 这些权限认证用RABC都很困难。 
    下面介绍 Auth权限认证, 它几乎是全能的, 除了能进行节点认证, 上面说的RABC很难认证的两种情况,它都能实现。 
    Auth权限认证是按规则进行认证。我先说说它的原理。 在数据库中我们有 规则表(think_auth_rule) ,用户组表(think_auth_group), 用户组明显表(think_auth_group_access)
    我们在规则表中定义权限规则 , 在用户组表中定义每个用户组有哪些权限规则,在用户组明显表中 定义用户所属的用户组。 下面举例说明。 
    我们要判断用户是否有显示一个操作按钮的权限, 首先定义一个规则, 在规则表中添加一个名为 show_button 的规则。 然后在用户组表添加一个用户组,定义这个用户组有show_button 的权限规则(think_auth_group表中rules字段存得时规则ID,多个以逗号隔开), 然后在用户组明细表定义 UID 为1 的用户 属于刚才这个的这个用户组。 
    ok,表数据定义好后, 判断权限很简单

        import('ORG.Util.Auth');//加载类库
         $auth=new Auth();
         if($auth->check('show_button',1)){// 第一个参数是规则名称,第二个参数是用户UID
          //有显示操作按钮的权限
        }else{
          //没有显示操作按钮的权限
        }

    Auth类同样可以做像RBAC一样的对节点进行认证。 我们只要将规则名称,定义为节点名称就行了。 
    和RABC一样 在公共控制器CommonAction 中定义_initialize 方法,

    <?php
     class CommonAction extends Action{
         public function _initialize(){
            import('ORG.Util.Auth');//加载类库
            $auth=new Auth();
            if(!$auth->check(MODULE_NAME.'-'.ACTION_NAME,session('uid'))){
                 $this->error('你没有权限');
            }
         }
     }

    这时候我们可以在数据库中添加的节点规则, 格式为: “控制器名称-方法名称”

    Auth 类 还可以多个规则一起认证 如: 

     $auth->check('rule1,rule2',uid); 

    表示 认证用户只要有rule1的权限或rule2的权限,只要有一个规则的权限,认证返回结果就为true 即认证通过。 默认多个权限的关系是 “or” 关系,也就是说多个权限中,只要有个权限通过则通过。 我们也可以定义为 “and” 关系

    $auth->check('rule1,rule2',uid,'and'); 

    第三个参数指定为"and" 表示多个规则以and关系进行认证, 这时候多个规则同时通过认证 才有权限。只要一个规则没有权限则就会返回false。

    Auth认证,一个用户可以属于多个用户组。 比如我们对 show_button这个规则进行认证, 用户A 同时属于 用户组1 和用户组2 两个用户组 , 用户组1 没有show_button 规则权限, 但如果用户组2 有show_button 规则权限,则一样会权限认证通过。

         $auth->getGroups(uid)
         

    通过上面代码,可以获得用户所属的所有用户组,方便我们在网站上面显示。

    Auth类还可以按用户属性进行判断权限, 比如 按照用户积分进行判断, 假设我们的用户表 (think_members) 有字段 score 记录了用户积分。 
    我在规则表添加规则时,定义规则表的condition 字段,condition字段是规则条件, 默认为空 表示没有附加条件, 用户组中只有规则 就通过认证。 如果定义了 condition字段, 用户组中有规则 不一定能通过认证, 程序还会判断是否满足 附加条件。 比如我们添加几条规则: 
    name字段: grade1 , condition字段: {score}<100 
    name字段: grade2, condition字段: {score}>100 and {score}<200
    name 字段: grade3, condition字段 : {score}>200 and {score}<300

    这里 {score} 表示 think_members 表 中字段 score的值。 

    那么这时候 
    $auth->check('grade1',uid) 是判断用户积分是不是0-100
    $auth->check('grade2',uid) 判断用户积分是不是在100-200
    $auth->check('grade3',uid) 判断用户积分是不是在200-300
    uth 类认证的使用方法 大致如上

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

    在使用Auth类前需要配置config.php

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

    需要导入数据库

    -- ----------------------------
     -- 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 '',  
         `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;

    二、步骤

    2.1

    新建Auth.php,复制下面的代码,把注释中的表都创建一下。把文件放到extend新建文件夹org放进去即可,
    <?php 
    // +----------------------------------------------------------------------
    // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
    // +----------------------------------------------------------------------
    // | Copyright (c) 2011 http://thinkphp.cn All rights reserved.
    // +----------------------------------------------------------------------
    // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
    // +----------------------------------------------------------------------
    // | Author: luofei614 <weibo.com/luofei614>
    // +----------------------------------------------------------------------
    // | 修改者: anuo (本权限类在原3.2.3的基础上修改过来的)
    // +----------------------------------------------------------------------
    use think\Db;
    use think\Config;
    use think\Session;
    use think\Request;
    use think\Loader; 
     
    /**
     * 权限认证类
     * 功能特性:
     * 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之间时这条规则才会通过。
     */
    //数据库
    /*
    -- ----------------------------
    -- 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;
     */
     
    class Auth
    {
        /**
         * @var object 对象实例
         */
        protected static $instance;
        /**
         * 当前请求实例
         * @var Request
         */
        protected $request;
     
        //默认配置
        protected $config = [
            'auth_on'           => 1, // 权限开关
            'auth_type'         => 1, // 认证方式,1为实时认证;2为登录认证。
            'auth_group'        => 'auth_group', // 用户组数据表名
            'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
            'auth_rule'         => 'auth_rule', // 权限规则表
            'auth_user'         => 'member', // 用户信息表
        ];
     
        /**
         * 类架构函数
         * Auth constructor.
         */
        public function __construct()
        {
            //可设置配置项 auth, 此配置项为数组。
            if ($auth = Config::get('auth')) {
                $this->config = array_merge($this->config, $auth);
            }
            // 初始化request
            $this->request = Request::instance();
        }
     
        /**
         * 初始化
         * @access public
         * @param array $options 参数
         * @return \think\Request
         */
        public static function instance($options = [])
        {
            if (is_null(self::$instance)) {
                self::$instance = new static($options);
            }
     
            return self::$instance;
        }
     
        /**
         * 检查权限
         * @param        $name     string|array  需要验证的规则列表,支持逗号分隔的权限规则或索引数组
         * @param        $uid      int           认证用户的id
         * @param int    $type     认证类型
         * @param string $mode     执行check的模式
         * @param string $relation 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
         * @return bool               通过验证返回true;失败返回false
         */
        public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or')
        {
            if (!$this->config['auth_on']) {
                return true;
            }
            // 获取用户需要验证的所有有效规则列表
            $authList = $this->getAuthList($uid, $type);
            if (is_string($name)) {
                $name = strtolower($name);
                if (strpos($name, ',') !== false) {
                    $name = explode(',', $name);
                } else {
                    $name = [$name];
                }
            }
            $list = []; //保存验证通过的规则名
            if ('url' == $mode) {
                $REQUEST = unserialize(strtolower(serialize($this->request->param())));
            }
            foreach ($authList as $auth) {
                $query = preg_replace('/^.+\?/U', '', $auth);
                if ('url' == $mode && $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;
                    }
                } else {
                    if (in_array($auth, $name)) {
                        $list[] = $auth;
                    }
                }
            }
            if ('or' == $relation && !empty($list)) {
                return true;
            }
            $diff = array_diff($name, $list);
            if ('and' == $relation && empty($diff)) {
                return true;
            }
     
            return false;
        }
     
        /**
         * 根据用户id获取用户组,返回值为数组
         * @param  $uid int     用户id
         * @return array       用户所属的用户组 array(
         *              array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
         *              ...)
         */
        public function getGroups($uid)
        {
            static $groups = [];
            if (isset($groups[$uid])) {
                return $groups[$uid];
            }
            // 转换表名
            $auth_group_access = Loader::parseName($this->config['auth_group_access'], 1);
            $auth_group        = Loader::parseName($this->config['auth_group'], 1);
            // 执行查询
            $user_groups  = Db::view($auth_group_access, 'uid,group_id')
                ->view($auth_group, 'title,rules', "{$auth_group_access}.group_id={$auth_group}.id", 'LEFT')
                ->where("{$auth_group_access}.uid='{$uid}' and {$auth_group}.status='1'")
                ->select();
            $groups[$uid] = $user_groups ?: [];
     
            return $groups[$uid];
        }
     
        /**
         * 获得权限列表
         * @param integer $uid 用户id
         * @param integer $type
         * @return array
         */
        protected function getAuthList($uid, $type)
        {
            static $_authList = []; //保存用户验证通过的权限列表
            $t = implode(',', (array)$type);
            if (isset($_authList[$uid . $t])) {
                return $_authList[$uid . $t];
            }
            if (2 == $this->config['auth_type'] && Session::has('_auth_list_' . $uid . $t)) {
                return Session::get('_auth_list_' . $uid . $t);
            }
            //读取用户所属用户组
            $groups = $this->getGroups($uid);
            $ids    = []; //保存用户所属用户组设置的所有权限规则id
            foreach ($groups as $g) {
                $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
            }
            $ids = array_unique($ids);
            if (empty($ids)) {
                $_authList[$uid . $t] = [];
     
                return [];
            }
            $map = [
                'id'   => ['in', $ids],
                'type' => $type
            ];
            //读取用户组所有权限规则
            $rules = Db::name($this->config['auth_rule'])->where($map)->field('condition,name')->select();
            //循环规则,判断结果。
            $authList = []; //
            foreach ($rules as $rule) {
                if (!empty($rule['condition'])) {
                    //根据condition进行验证
                    $user    = $this->getUserInfo($uid); //获取用户信息,一维数组
                    $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
                    @(eval('$condition=(' . $command . ');'));
                    if ($condition) {
                        $authList[] = strtolower($rule['name']);
                    }
                } else {
                    //只要存在就记录
                    $authList[] = strtolower($rule['name']);
                }
            }
            $_authList[$uid . $t] = $authList;
            if (2 == $this->config['auth_type']) {
                //规则列表结果保存到session
                Session::set('_auth_list_' . $uid . $t, $authList);
            }
     
            return array_unique($authList);
        }
     
        /**
         * 获得用户资料
         * @param $uid
         * @return mixed
         */
        protected function getUserInfo($uid)
        {
            static $user_info = [];
     
            $user = Db::name($this->config['auth_user']);
            // 获取用户表主键
            $_pk = is_string($user->getPk()) ? $user->getPk() : 'uid';
            if (!isset($user_info[$uid])) {
                $user_info[$uid] = $user->where($_pk, $uid)->find();
            }
     
            return $user_info[$uid];
        }
    }

    2.2 

    <?php
    namespace app\admin\controller;
    use \think\Controller;
    use think\Loader;
    class Base extends Controller
    {
        protected $current_action;
        public function _initialize()
        {
            Loader::import("org/Auth", EXTEND_PATH);
            $auth=new \Auth();
            $this->current_action = request()->module().'/'.request()->controller().'/'.lcfirst(request()->action());
            $result = $auth->check($this->current_action,session('user_id'));
            if($result){
                echo "权限验证成功";
            }
        }
    }

    参考:http://www.thinkphp.cn/topic/4029.html

    https://blog.csdn.net/qq_33257081/article/details/79137190

    https://www.cnblogs.com/gggzly/p/5985392.html

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

    展开全文
  • 权限管理是一个项目中必不可少的模块之一,常用的有RBAC、Auth等。本文就分享在TP5中通过Auth验证权限的实例,希望对大家有所帮助。

    权限管理是一个项目中必不可少的模块之一,常用的有RBAC、Auth等。本文就分享在TP5中通过Auth验证权限的实例,希望对大家有所帮助。<?php

    namespace think;

    use think\Config;

    use think\Session;

    use think\Db;

    /**

    * 权限认证类

    */

    //数据库

    /*

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

    -- mt4_auth_rule,规则表,

    -- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证

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

    DROP TABLE IF EXISTS `mt4_auth_rule`;

    CREATE TABLE `mt4_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;

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

    -- mt4_auth_group 用户组表,

    -- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用

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

    DROP TABLE IF EXISTS `mt4_auth_group`;

    CREATE TABLE `mt4_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;

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

    -- mt4_auth_group_access 用户组明细表

    -- uid:用户id,group_id:用户组id

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

    DROP TABLE IF EXISTS `mt4_auth_group_access`;

    CREATE TABLE `mt4_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;

    */

    class Auth {

    //默认配置

    protected $config = array(

    'auth_on' => true, // 认证开关

    'auth_type' => 2, // 认证方式,1为实时认证;2为登录认证。

    'auth_group' => 'auth_group', // 用户组数据表名

    'auth_group_access' => 'auth_group_access', // 用户-用户组关系表

    'auth_rule' => 'auth_rule', // 权限规则表

    'auth_user' => 'auth_admin' // 用户信息表

    );

    public function __construct() {

    if (Config::get('auth_config')) {

    $this->config = array_merge($this->config, Config::get('auth_config')); //可设置配置项 auth_config, 此配置项为数组。

    }

    }

    /**

    * 检查权限

    * @param name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组

    * @param uid int 认证用户的id

    * @param string mode 执行check的模式

    * @param relation string 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证

    * return boolean 通过验证返回true;失败返回false

    */

    public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or') {

    if (!$this->config['auth_on']) {

    return true;

    }

    $authList = $this->getAuthList($uid, $type); //获取用户需要验证的所有有效规则列表

    if (is_string($name)) {

    $name = strtolower($name);

    // if (strpos($name, ',') !== false) {

    // $name = explode(',', $name);

    // } else {

    // $name = [$name];

    // }

    $name = strpos($name, ',') !== false ? explode(',', $name) : [$name];

    }

    $list = []; //保存验证通过的规则名

    if ($mode == 'url') {

    $REQUEST = unserialize(strtolower(serialize($_REQUEST)));

    }

    foreach ($authList as $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;

    }

    } else if (in_array($auth, $name)) {

    $list[] = $auth;

    }

    }

    if ($relation == 'or' and ! empty($list)) {

    return false;

    }

    $diff = array_diff($name, $list);

    if ($relation == 'and' and empty($diff)) {

    return false;

    }

    return true;

    }

    /**

    * 根据用户id获取用户组,返回值为数组

    * @param uid int 用户id

    * return array 用户所属的用户组 [

    * ['uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),

    * ...)

    */

    public function getGroups($uid) {

    static $groups = [];

    if (isset($groups[$uid])) {

    return $groups[$uid];

    }

    $user_groups = Db::view($this->config['auth_group_access'], 'uid,group_id')->view($this->config['auth_group'], 'title,rules', "{$this->config['auth_group_access']}.group_id={$this->config['auth_group']}.id")

    ->where(['uid' => $uid, 'status' => 1])->select();

    $groups[$uid] = $user_groups ? $user_groups : [];

    return $groups[$uid];

    }

    /**

    * 获得权限列表

    * @param integer $uid 用户id

    * @param integer $type

    */

    protected function getAuthList($uid, $type) {

    static $_authList = []; //保存用户验证通过的权限列表

    $t = implode(',', (array) $type);

    if (isset($_authList[$uid . $t])) {

    return $_authList[$uid . $t];

    }

    if ($this->config['auth_type'] == 2 && Session::has('_auth_list_' . $uid . $t)) {

    return Session::get('_auth_list_' . $uid . $t);

    }

    //读取用户所属用户组

    $groups = $this->getGroups($uid);

    $ids = []; //保存用户所属用户组设置的所有权限规则id

    foreach ($groups as $g) {

    $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));

    }

    $ids = array_unique($ids);

    if (empty($ids)) {

    $_authList[$uid . $t] = [];

    return [];

    }

    $map = [

    'id' => ['notin', $ids],

    'type' => $type,

    'status' => 1,

    ];

    //读取用户组所有权限规则

    $rules = Db::name($this->config['auth_rule'])->where($map)->field('condition,name')->select();

    //循环规则,判断结果。

    $authList = []; //

    foreach ($rules as $rule) {

    if (!empty($rule['condition'])) { //根据condition进行验证

    $this->getUserInfo($uid); //获取用户信息,一维数组

    $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);

    @(eval('$condition=(' . $command . ');'));

    $condition && $authList[] = strtolower($rule['name']);

    } else {

    $authList[] = strtolower($rule['name']); //只要存在就记录

    }

    }

    $_authList[$uid . $t] = $authList;

    if ($this->config['auth_type'] == 2) {

    $_SESSION['_auth_list_' . $uid . $t] = $authList; //规则列表结果保存到session

    }

    return array_unique($authList);

    }

    /**

    * 获得用户资料,根据自己的情况读取数据库

    */

    protected function getUserInfo($uid) {

    static $userinfo = [];

    if (!isset($userinfo[$uid])) {

    $userinfo[$uid] = Db::name($this->config['auth_user'])->where(['uid' => $uid])->find();

    }

    return $userinfo[$uid];

    }

    }

    相关推荐:

    展开全文
  • 使用TP5开发的权限管理系统
  • thinkphp5 权限认证 RBAC 加 行为日志这个插件主要有一整套RBAC 行为日志 视图 只需要 composer安装即可和你的系统... composer require tekintian/tp5auth新加入方法is_login() 判断是否登录login($uid 用户ID,$...
  • tp5 后台auth权限问题

    2019-09-09 09:37:20
    刚刚做了个后台,想添加一个权限,分为普通管理员和超级管理员,应该怎么实现?
  • 最新基于TP5通用后台Auth权限管理系统,对于学习TP5的同学,能尽快的熟悉和上手了解TP5的特性
  • TP5+AUTH权限的一些理解避免踩坑

    千次阅读 2018-05-17 10:41:28
    下面本人为大家讲解一下如何实现auth权限,第一步,新建Auth.php,复制下面的代码,把注释中的表都创建一下。把文件放到extend新建文件夹org放进去即可,&lt;?php // +---------------------------------------...
  • tp5---auth权限搭建2

    2018-01-06 17:07:00
    1、auth权限 composer auth库 下载完成之后 根据auth.php中所提及怎样创建表,就怎样建表 2、安利一个简单的建表操作 根据composer下载里的文件注释的代码,将其直接放到sql编辑器里就好 CREATE TABLE think_...
  • 今天我下决心用一天到两天的时间一定一步一步在tp5里面实现。 RBAC 1、rbac的实现依赖以下几个composer组件 composer require gmars/tp5-nestedsets composer require gmars/tp5-rbac 由于RBAC组件需要数据库...
  • tp5框架的Auth类可以实现页面的访问权限,还可以精确到页面上的按钮。页面访问主要靠rule表的name字段。附加条件权限主要看condition字段。源码下载:https://files.cnblogs.com/files/mzzone/...
  • TP5.auth角色权限管理(官方demo)开源代码 适合小白借鉴学习-附件资源
  • 超级简单易懂的auth权限管理的demo,适合小白学习,数据库还有说明文档都有只要不嫌枯燥认真看完说明文档就会话不多说直接链接走起,小白自行下载访问演示,不懂的里面含数据库和说明文档,代码也都写了注释 ...
  • 基于tp5 开发的后台通用系统 php版本5.6 以上 把更目录数据库导入你自己数据 修改配置database.php里面数据库配置信息改变成 登录账号:admin 登录密码:www.wazyb.com 解压密码:www.wazyb.com@20171222auth
  • tp5适合初学者学习,完整资源包【程序数据库静态资源】,如果你想学thinkphp5的话,可以下载,看看里面的语法,完整资源包,跟着说明操作,就可以完成安装,含前后端模板
  • Auth权限验证

    2017-08-23 16:25:33
    TP5权限验证类(Auth)
  • tp5-auth这是一个基于ThinkPHP5框架的Auth类库案例展示基于ThinkPHP5开发呈现权限管理的效果安装composer require zhujinkui/tp5-auth说明AUTH(基于用户角色的访问控制),就是用户通过角色与权限进行关联。...
  • TP5后台Auth认证实现详解

    千次阅读 2019-07-16 15:20:57
    例如有的是文章发布员角色的管理员 他只能使用后台发布文章的功能 而其他功能没有权限访问 诸如此类! 建表(c_为表名前缀) ...权限表(也就是每个模板的每个访问路径都是一个权限) c_auth_rule 管...
  • tp5--权限操作(auth类)基本使用

    万次阅读 2017-08-28 20:46:06
    三张表,分别是权限表,用户组表,管理员和用户组关联表 权限表:存储每一个权限 用户组表: 给不同的用户组添加不同的权限,添加管理员时将管理员加入某个用户组,该管理员拥有了该权限组里的所有权限 管理表: 将...
  • php的auth权限类源码

    千次阅读 2017-08-17 23:02:42
    tp5中将auth类去除了,所以需要自己引入进去,这是tp3的auth权限类源码,用的时候将auth的三张数据表名改成自己的。 // +---------------------------------------------------------------------- // | ThinkPHP ...
  • tp5权限 简单的

    2019-06-10 09:42:37
    首先创建管理员表 admin ...从总后台将用户角色写入数据库 并将权限写入数据库 在角色列表授拳权限写入ruler_auth表中 然后在左侧菜单栏公共的部分写入判断 判断当前用户的角色 以及对应的权限 //获取管理员角色...

空空如也

空空如也

1 2 3
收藏数 45
精华内容 18
关键字:

tp5auth权限