我的一些个人理解,还是有些不懂的地方,有错误请指正,谢谢!!!

class Auth{

    //默认配置
protected $_config = array(
'auth_on' => true, // 认证开关
'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
'auth_group' => 'auth_group', // 用户组数据表名
'auth_group_access' =>'auth_group_access', // 用户-用户组关系表
'auth_rule' => 'auth_rule', // 权限规则表
'auth_user' => 'member' // 用户信息表
); public function __construct() {
if (config('auth_config')) {
//可设置配置项 auth_config, 此配置项为数组。
$this->_config = array_merge($this->_config, config('auth_config'));
//不知道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; //小写的组下全部权限名称name(一维数组)
$authList = $this->getAuthList($uid,$type); //获取用户需要验证的所有有效规则列表 /*array( [0] =>controller/funtion,[1] => controller/funtion,[2]...... ) */ //判断name是什么类型,并 全部转化成array类型
if (is_string($name)) {
$name = strtolower($name);//转小写
if (strpos($name, ',') !== false) {//查找 "," 在字符串中第一次出现的位置:返回数字
$name = explode(',', $name);//一维数组
} else {
$name = array($name);//一维数组
}
// $name = strpos($name, ',') !== false ? explode(',', $name) : [$name];
}
$list = array(); //保存验证通过的规则名
if ($mode=='url') {
//serialize() 返回字符串,此字符串包含了表示 value 的字节流,可以存储于任何地方。
//strtolower:把所有字符转换为小写:
//unserialize:从已存储的表示中创建 PHP 的值
$REQUEST = unserialize( strtolower(serialize($_REQUEST)) );
} //两种种比较方法!!!
//if ($mode=='url' && $query!=$auth ) 节点相符且url参数满足
//in_array($auth , $name) name在auth存在对应 foreach ( $authList as $auth ) {
$query = preg_replace('/^.+\?/U','',$auth);
if ($mode=='url' && $query!=$auth ) { //当赋予的权限和url上的路径不一样的时候的做法
// //把查询字符串解析到变量中:
parse_str($query,$param); //解析规则中的param
/*$param = array(1) {
["controller/index"] => string(0) ""
}*/ //array_intersect_assoc比较两个数组的键名和键值,并返回交集:
$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 ;
}
} // or 和 and
if ($relation == 'or' and !empty($list)) {
return true;
}
//比较两个数组的键值,并返回差集:
$diff = array_diff($name, $list);//返回都没有的值
if ($relation == 'and' and 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 = 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.uid='$uid' and g.status='1'")
->field('uid,group_id,title,rules')->select();
/*$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 : array();
return $groups[$uid];
} /**
* 获得权限列表
* @param integer $uid 用户id
* @param integer $type
* @param $_SESSION['_auth_list_'.$uid.$t] = $_authList[$uid.$t] = 权限($name(array))一维数组 array( [0] =>controller/funtion,[1] => controller/funtion,[2]...... )
*/
protected function getAuthList($uid,$type) {
static $_authList = array(); //保存用户验证通过的权限列表 //implode: 把数组元素组合为字符串
$t = implode(',',(array)$type);// if (isset($_authList[$uid.$t])) {// 已经获取到权限name的 直接返回
return $_authList[$uid.$t];
} //登录才需要用到的判断
if( $this->_config['auth_type']==2 && isset($_SESSION['_auth_list_'.$uid.$t])){//1 && _auth_list_241
return $_SESSION['_auth_list_'.$uid.$t];
} //读取用户所属用户组 'uid,group_id,title,rules(字符串,权限id)'二维数组,其实只要一组数据而已【0】
$groups = $this->getGroups($uid); $ids = array();//保存用户所属用户组设置的所有权限规则id
foreach ($groups as $g) {
//trim: 移除字符串左侧的字符
//explode: 把字符串打散为数组
$ids = array_merge($ids, explode(',', trim($g['rules'], ',')));//一维数组
}
//array_unique: 移除数组中重复的值
$ids = array_unique($ids); //如果没有权限就返回一个空数组
if (empty($ids)) {
$_authList[$uid.$t] = array();
return array();
} $map=array(
'id'=>array('in',$ids),
'type'=>$type,
'status'=>1,
);
//读取用户组所有权限规则
$rules = \think\Db::name($this->_config['auth_rule'])->where($map)->field('condition,name')->select();//二维数组
/*
* array(3) {
[0] => array(2) {
["condition"] => string(0) ""
["name"] => string(8) "conf/add"
}
[1] => array(2) {
["condition"] => string(0) ""
["name"] => string(8) "conf/del"
}
[2] => array(2) {
["condition"] => string(0) ""
["name"] => string(8) "link/del"
}
}
* */ //循环规则,判断结果。
$authList = array(); //
foreach ($rules as $rule) {
if (!empty($rule['condition'])) { //根据condition进行验证
$user = $this->getUserInfo($uid);//获取用户全部信息,一维数组 //preg_replace:替一个正则表达式的搜索和替换, 参数一:搜索,参数二:替换,参数三:要搜索替换的目标字符串或字符串数组
//试了一下,不知道有什么用,$rule['condition']是什么,输出的也一样,没变!
//我觉得那个condition就是在这里用正则判断的
$command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']);
//dump($command);//debug
//eval() 函数把字符串按照 PHP 代码来计算。
//$$command是什么,$condition就是什么,输出的也一样,没变!
@(eval('$condition=(' . $command . ');'));
if ($condition) {
//strtolower: 把所有字符转换为小写:
$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;
}
return array_unique($authList);
} /**
* 获得用户资料,根据自己的情况读取数据库
*/
protected function getUserInfo($uid) {
static $userinfo=array();
if(!isset($userinfo[$uid])){
$userinfo[$uid]=\think\Db::name($this->_config['auth_user'])->where(array('uid'=>$uid))->find();
}
return $userinfo[$uid];
} }

对那个     登录认证   还是不是很懂!!!

最新文章

  1. 深入理解C#
  2. Android系统启动过程
  3. 开发adobe ane分享
  4. JQuery Easy Ui 可装载组合框 - ComboBox
  5. php 得到一个文件夹下的所有文件,包括子文件中的文件
  6. mysql创建表与索引
  7. HDU 1548 A strange lift 奇怪的电梯(BFS,水)
  8. Cocos开发中性能优化工具介绍之Xcode中Instruments工具使用
  9. 将控制台程序做成windows服务
  10. MySQLdb callproc 方法
  11. Jquery 中each循环嵌套的使用示例教程
  12. java类固定值代替基表写法
  13. Ubuntu忘记密码后强制修改密码
  14. Description Resource Path Location Type Java compiler level does not match the version of(编译问题)
  15. How to vi
  16. 160多个android开源码汇总
  17. Lucene Query In Kibana
  18. (排序算法整理)NEFU 30/32
  19. oss上传文件夹-cloud2-泽优软件
  20. C++11:实用特性

热门文章

  1. 模块 psutil 系统信息获取
  2. c期末笔记(4)
  3. 使用css动画实现领积分效果
  4. Hadoop安装教程_伪分布式
  5. GitHub+PicGo构建免费图床及其高效使用
  6. .Net Core结合AspNetCoreRateLimit实现限流
  7. Java编程最差实践常见问题详细说明(2)转
  8. stand up meeting 12-7
  9. stand up meeting 12/17/2015
  10. 二分例题 51nod