RbacAuth.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. namespace App\Servers\Auth;
  3. use Illuminate\Support\Facades\DB;
  4. /**
  5. * RBAC验证类
  6. */
  7. class RbacAuth
  8. {
  9. // 表前缀
  10. private $prefix = '';
  11. //默认配置
  12. protected $_config = array(
  13. 'auth_on' => true, // 认证开关
  14. 'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
  15. 'auth_group' => 'auth_group', // 用户组数据表名
  16. 'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
  17. 'auth_rule' => 'auth_rule' // 权限规则表
  18. );
  19. /**
  20. * $prefix表前缀
  21. */
  22. public function __construct($prefix='')
  23. {
  24. $this->prefix = $prefix;
  25. $prefix = $prefix;
  26. $this->_config['auth_group'] = $prefix . $this->_config['auth_group'];
  27. $this->_config['auth_rule'] = $prefix . $this->_config['auth_rule'];
  28. $this->_config['auth_group_access'] = $prefix . $this->_config['auth_group_access'];
  29. if ( config('AUTH_CONFIG') ) {
  30. //可设置配置项 AUTH_CONFIG, 此配置项为数组。
  31. $this->_config = array_merge($this->_config, config('AUTH_CONFIG'));
  32. }
  33. }
  34. /**
  35. * 检查权限
  36. * @param name string|array 需要验证的规则列表,支持逗号分隔的权限规则或索引数组
  37. * @param uid int 认证用户的id
  38. * @param string mode 执行check的模式
  39. * @param relation string 如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证
  40. * @return boolean 通过验证返回true;失败返回false
  41. */
  42. public function check($name, $uid, $type = 1, $mode = 'url', $relation = 'or')
  43. {
  44. if (!$this->_config['auth_on']) {
  45. return true;
  46. }
  47. $authList = $this->getAuthList($uid, $type); //获取用户需要验证的所有有效规则列表
  48. if (is_string($name)) {
  49. $name = strtolower($name);
  50. if (strpos($name, ',') !== false) {
  51. $name = explode(',', $name);
  52. } else {
  53. $name = array($name);
  54. }
  55. }
  56. $list = array(); //保存验证通过的规则名
  57. if ($mode == 'url') {
  58. $REQUEST = unserialize(strtolower(serialize($_REQUEST)));
  59. }
  60. foreach ($authList as $auth) {
  61. $query = preg_replace('/^.+\?/U', '', $auth);
  62. if ($mode == 'url' && $query != $auth) {
  63. parse_str($query, $param); //解析规则中的param
  64. $intersect = array_intersect_assoc($REQUEST, $param);
  65. $auth = preg_replace('/\?.*$/U', '', $auth);
  66. if (in_array($auth, $name) && $intersect == $param) {
  67. //如果节点相符且url参数满足
  68. $list[] = $auth;
  69. }
  70. } else if (in_array($auth, $name)) {
  71. $list[] = $auth;
  72. }
  73. }
  74. if ($relation == 'or' and !empty($list)) {
  75. return true;
  76. }
  77. $diff = array_diff($name, $list);
  78. if ($relation == 'and' and empty($diff)) {
  79. return true;
  80. }
  81. return false;
  82. }
  83. /**
  84. * 根据用户id获取用户组,返回值为数组
  85. * @param uid int 用户id
  86. * @return array 用户所属的用户组 array(
  87. * array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
  88. * ...)
  89. */
  90. public function getGroups($uid)
  91. {
  92. static $groups = array();
  93. if (isset($groups[$uid])) {
  94. return $groups[$uid];
  95. }
  96. $groups = DB::table($this->_config['auth_group_access'] . ' a')
  97. ->where("a.user_uid='$uid' and g.status='1'")
  98. ->join($this->_config['auth_group'] . " g", " a.group_id=g.id")
  99. ->select(['user_uid as uid','group_id','title','rules'])->get()->toArray();
  100. $groups[$uid] = $groups ?: array();
  101. return $groups[$uid];
  102. }
  103. /**
  104. * 获得权限列表
  105. * @param integer $uid 用户id
  106. * @param integer $type
  107. */
  108. protected function getAuthList($uid, $type)
  109. {
  110. static $_authList = array(); //保存用户验证通过的权限列表
  111. $t = implode(',', (array) $type);
  112. if (isset($_authList[$uid . $t])) {
  113. return $_authList[$uid . $t];
  114. }
  115. if ($this->_config['auth_type'] == 2) {
  116. $session=session('_AUTH_LIST_'.$this->prefix.$uid.$t);
  117. if(isset($session))
  118. return $session;
  119. }
  120. //读取用户所属用户组
  121. $groups = $this->getGroups($uid);
  122. $ids = array(); //保存用户所属用户组设置的所有权限规则id
  123. foreach ($groups as $g) {
  124. //dump($g);
  125. if(isset($g['rules']))
  126. $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));
  127. }
  128. $ids = array_unique($ids);
  129. if (empty($ids)) {
  130. $_authList[$uid . $t] = array();
  131. return array();
  132. }
  133. $map = [['menu_id','IN',$ids]];
  134. // 读取用户组所有权限规则
  135. $rules = DB::table($this->_config['auth_rule'])->where($map)->select(['name'])->get()->toArray();
  136. // 循环规则,判断结果。
  137. $authList = array(); //
  138. foreach ($rules as $rule) {
  139. $authList[] = strtolower($rule['name']);
  140. }
  141. $_authList[$uid . $t] = $authList;
  142. if ($this->_config['auth_type'] == 2) {
  143. //规则列表结果保存到session
  144. session('_AUTH_LIST_'.$this->prefix.$uid.$t,$authList);
  145. }
  146. return array_unique($authList);
  147. }
  148. }