thinkPHP 3.1.3 Auth权限修改版

jerry thinkphp 2015年11月19日 收藏
thinkPHP 3.1.3 Auth权限修改版,支持只验证规则表有的数据!

这是我发布的问题:http://www.thinkphp.cn/topic/16890.html

视乎没什么好方法满足我的要求了,无奈打开Auth.class.php来修改!

我的QQ:171313244
我很无奈只能修改了,原作者我实在没办法啊!
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2011 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: luofei614 <weibo.com/luofei614> 
  10. // +----------------------------------------------------------------------
  11. /**
  12.  * 权限认证类
  13.  * 功能特性:
  14.  * 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。
  15.  *      $auth=new Auth();  $auth->check('规则名称','用户id')
  16.  * 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and)
  17.  *      $auth=new Auth();  $auth->check('规则1,规则2','用户id','and') 
  18.  *      第三个参数为and时表示,用户需要同时具有规则1和规则2的权限。 当第三个参数为or时,表示用户值需要具备其中一个条件即可。默认为or
  19.  * 3,一个用户可以属于多个用户组(think_auth_group_access表 定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group 定义了用户组权限)
  20.  * 
  21.  * 4,支持规则表达式。
  22.  *      在think_auth_rule 表中定义一条规则时,如果type为1, condition字段就可以定义规则表达式。 如定义{score}>5  and {score}<100  表示用户的分数在5-100之间时这条规则才会通过。
  23.  * @category ORG
  24.  * @package ORG
  25.  * @subpackage Util
  26.  * @author luofei614<weibo.com/luofei614>
  27.  */

  28. //数据库
  29. /*
  30. -- ----------------------------
  31. -- think_auth_rule,规则表,
  32. -- id:主键,name:规则唯一标识, title:规则中文名称 status 状态:为1正常,为0禁用,condition:规则表达式,为空表示存在就验证,不为空表示按照条件验证
  33. -- ----------------------------
  34.  DROP TABLE IF EXISTS `think_auth_rule`;
  35. CREATE TABLE `think_auth_rule` (  
  36.     `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,  
  37.     `name` char(80) NOT NULL DEFAULT '',  
  38.     `title` char(20) NOT NULL DEFAULT '',  
  39.     `status` tinyint(1) NOT NULL DEFAULT '1',  
  40.     `condition` char(100) NOT NULL DEFAULT '',  
  41.     PRIMARY KEY (`id`),  
  42.     UNIQUE KEY `name` (`name`)
  43. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
  44. -- ----------------------------
  45. -- think_auth_group 用户组表, 
  46. -- id:主键, title:用户组中文名称, rules:用户组拥有的规则id, 多个规则","隔开,status 状态:为1正常,为0禁用
  47. -- ----------------------------
  48.  DROP TABLE IF EXISTS `think_auth_group`;
  49. CREATE TABLE `think_auth_group` ( 
  50.     `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
  51.     `title` char(100) NOT NULL DEFAULT '', 
  52.     `status` tinyint(1) NOT NULL DEFAULT '1', 
  53.     `rules` char(80) NOT NULL DEFAULT '', 
  54.     PRIMARY KEY (`id`)
  55. ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
  56. -- ----------------------------
  57. -- think_auth_group_access 用户组明细表
  58. -- uid:用户id,group_id:用户组id
  59. -- ----------------------------
  60. DROP TABLE IF EXISTS `think_auth_group_access`;
  61. CREATE TABLE `think_auth_group_access` (  
  62.     `uid` mediumint(8) unsigned NOT NULL,  
  63.     `group_id` mediumint(8) unsigned NOT NULL, 
  64.     UNIQUE KEY `uid_group_id` (`uid`,`group_id`),  
  65.     KEY `uid` (`uid`), 
  66.     KEY `group_id` (`group_id`)
  67. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  68.  */

  69. class Auth{

  70.     //默认配置
  71.     protected $_config = array(
  72.         'AUTH_ON' => true, //认证开关
  73.         'AUTH_TYPE' => 1, // 认证方式,1为时时认证;2为登录认证。
  74.         'AUTH_GROUP' => 'think_auth_group', //用户组数据表名
  75.         'AUTH_GROUP_ACCESS' => 'think_auth_group_access', //用户组明细表
  76.         'AUTH_RULE' => 'think_auth_rule', //权限规则表
  77.         'AUTH_USER' => 'think_members'//用户信息表
  78.     );

  79.     public function __construct() {
  80.         if (C('AUTH_CONFIG')) {
  81.             //可设置配置项 AUTH_CONFIG, 此配置项为数组。
  82.             $this->_config = array_merge($this->_config, C('AUTH_CONFIG'));
  83.         }
  84.     }

  85.     //获得权限$name 可以是字符串或数组或逗号分割, uid为 认证的用户id, $or 是否为or关系,为true是, name为数组,只要数组中有一个条件通过则通过,如果为false需要全部条件通过。
  86.     public function check($name, $uid, $relation='or') {
  87.         if (!$this->_config['AUTH_ON'])
  88.             return true;
  89.             $count = M()->table($this->_config['AUTH_RULE'])->where('name="'.$name.'"')->count();
  90.             if ($count == 0) {
  91.                 return true;
  92.             }
  93.         $authList = $this->getAuthList($uid);
  94.         if (is_string($name)) {
  95.             if (strpos($name, ',') !== false) {
  96.                 $name = explode(',', $name);
  97.             } else {
  98.                 $name = array($name);
  99.             }
  100.         }
  101.         $list = array(); //有权限的name
  102.         foreach ($authList as $val) {
  103.             if (in_array($val, $name))
  104.                 $list[] = $val;
  105.         }
  106.         if ($relation=='or' and !empty($list)) {
  107.             return true;
  108.         }
  109.         $diff = array_diff($name, $list);
  110.         if ($relation=='and' and empty($diff)) {
  111.             return true;
  112.         }
  113.         return false;
  114.     }

  115.     //获得用户组,外部也可以调用
  116.     public function getGroups($uid) {
  117.         static $groups = array();
  118.         if (isset($groups[$uid]))
  119.             return $groups[$uid];
  120.         $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.group_id=g.id")->select();
  121.         $groups[$uid]=$user_groups?$user_groups:array();
  122.         return $groups[$uid];
  123.     }

  124.     //获得权限列表
  125.     protected function getAuthList($uid) {
  126.         static $_authList = array();
  127.         if (isset($_authList[$uid])) {
  128.             return $_authList[$uid];
  129.         }
  130.         if(isset($_SESSION['_AUTH_LIST_'.$uid])){
  131.             return $_SESSION['_AUTH_LIST_'.$uid];
  132.         }
  133.         //读取用户所属用户组
  134.         $groups = $this->getGroups($uid);
  135.         $ids = array();
  136.         foreach ($groups as $g) {
  137.             $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
  138.         }
  139.         $ids = array_unique($ids);
  140.         if (empty($ids)) {
  141.             $_authList[$uid] = array();
  142.             return array();
  143.         }
  144.         //读取用户组所有权限规则
  145.         $map=array(
  146.             'id'=>array('in',$ids),
  147.             'status'=>1
  148.         );
  149.         $rules = M()->table($this->_config['AUTH_RULE'])->where($map)->select();
  150.         //循环规则,判断结果。
  151.         $authList = array();
  152.         foreach ($rules as $r) {
  153.             if (!empty($r['condition'])) {
  154.                 //条件验证
  155.                 $user = $this->getUserInfo($uid);
  156.                 $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $r['condition']);
  157.                 //dump($command);//debug
  158.                 @(eval('$condition=(' . $command . ');'));
  159.                 if ($condition) {
  160.                     $authList[] = $r['name'];
  161.                 }
  162.             } else {
  163.                 //存在就通过
  164.                 $authList[] = $r['name'];
  165.             }
  166.         }
  167.         $_authList[$uid] = $authList;
  168.         if($this->_config['AUTH_TYPE']==2){
  169.             //session结果
  170.             $_SESSION['_AUTH_LIST_'.$uid]=$authList;
  171.         }
  172.         return $authList;
  173.     }
  174.     //获得用户资料,根据自己的情况读取数据库
  175.     protected function getUserInfo($uid) {
  176.         static $userinfo=array();
  177.         if(!isset($userinfo[$uid])){
  178.              $userinfo[$uid]=M()->table($this->_config['AUTH_USER'])->find($uid);
  179.         }
  180.         return $userinfo[$uid];
  181.     }
  182. }