1, // 权限开关 'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。 'auth_group' => 'auth_group', // 用户组数据表名 'auth_group_access' => 'auth_group_access', // 用户-用户组关系表 'auth_rule' => 'auth_rule', // 权限规则表 'auth_user' => 'user', // 用户信息表 ]; /** * 类架构函数 * Auth constructor. */ private function __construct() { //可设置配置项 auth, 此配置项为数组。 if ($auth = Config::get('auth')) { $this->config = array_merge($this->config, $auth); } // 初始化request $this->request = Request::instance(); if (!defined('SITE_ID')) { return false; } $this->site_id = SITE_ID; } public function __clone() { // TODO: Implement __clone() method. } /** * 初始化 * @access public * @param array $options 参数 * @return \think\Request */ public static function getInstance($options = []) { if (is_null(self::$instance)) { self::$instance = new self($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; } //判断是否配置文件中放行的url if (in_array(strtolower($name), array_keys(array_change_key_case($this->config['auth_filter_model'])))) { return true; } // 获取用户需要验证的所有有效规则列表 $authList = $this->getAuthList($uid, $type, false, 2); 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 getUserGroups(int $uid = 0) { static $groups = []; if (isset($groups[$uid])) { return $groups[$uid]; } // 转换表名 $auth_group_access = $this->config['auth_group_access']; $auth_group = $this->config['auth_group']; // 执行查询 $user_groups = Db::view([$auth_group_access => $auth_group_access], 'uid,group_id') ->view([$auth_group => $auth_group], 'id,title,role_code,rules', "{$auth_group_access}.group_id={$auth_group}.id", 'LEFT') ->where("{$auth_group_access}.uid='{$uid}' and {$auth_group}.status='1'") ->select()->toArray(); $groups[$uid] = $user_groups ?: []; return $groups[$uid]; } /** * 获取系统所有角色 * @return \think\Collection * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getGroups() { $title = $this->request->param('title', ''); $role_code = $this->request->param('role_code', ''); $page = $this->request->param('page', 1, 'intval'); $limit = $this->request->param('limit', 10, 'intval'); $_db = Db::table($this->config['auth_group']); $_db->where('site_id', $this->site_id); //搜索角色名称 empty($title) ? '' : $_db->where('title', 'like', '%' . $title . '%'); empty($role_code) ? '' : $_db->where('role_code', 'like', '%' . $role_code . '%'); $_groups = $_db->where('type', 1)->page($page, $limit)->select(); if (!$_groups->isEmpty()) { $_groups = $_groups->toArray(); array_walk($_groups, function (&$v, $k) { $v['update_time'] = date('Y-m-d H:i:s', $v['update_time']); $v['create_time'] = date('Y-m-d H:i:s', $v['create_time']); }); } return $_groups; } /** * 根据用户角色组ID获取用户角色组权限菜单 * @param string $id * @return array|void * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function getGroupRule(int $id = 0) { if (!$id) { return; } $_db = Db::table($this->config['auth_group']); $_db->where('site_id', $this->site_id); $_data = $_db->field('rules')->find($id); if (empty($_data)) { return; } if(SITE_ID == 1){ $_rules = Db::table($this->config['auth_rule'])->select(); }else{ $_rules = Db::table($this->config['auth_rule'])->where('is_manager_use',0)->select(); } $_data = explode(',', $_data['rules']); if (!$_rules->isEmpty()) { $_rules = $_rules->toArray(); array_walk($_rules, function (&$v) use ($_data) { $v['title'] = $v['name']; $v['checked'] = in_array($v['id'], $_data) ? true : false; $v['children'] = null; $v['open'] = true; }); return $_rules; } return; } /** * 添加用户到用户角色组关系 * @param array $_data * @return int|string */ public function addUserGroupAccess(int $user_id, array $_data = []) { if (empty($_data) || empty($user_id)) { return true; } $_db = Db::table($this->config['auth_group_access']); //添加之前先删除已有的用户角色所有权限 $_db->where('site_id', $this->site_id)->where('uid', $user_id)->delete(); foreach ($_data as $k => $v) { $insert_data[$k]['site_id'] = $this->site_id; $insert_data[$k]['uid'] = $user_id; $insert_data[$k]['group_id'] = $v; $insert_data[$k]['update_time'] = $insert_data[$k]['create_time'] = time(); } $affected = $_db->strict(false)->insertAll($insert_data); return $affected; } /** * 添加权限菜单用户角色组 * @param array $_data * @return int|string */ public function addGroupRule(int $role_id = 0, string $menu_id = '') { $_data['site_id'] = $this->site_id; $_data['update_time'] = time(); $_data['rules'] = $menu_id; $_db = Db::table($this->config['auth_group']); $_db->where('id', $role_id); $affected = $_db->strict(false)->save($_data); ActionLog::getInstance()->write($_data, [], $_db->getLastSql()); return $affected; } /** * 添加系统用户角色组 * @param array $_data * @return int|string */ public function addGroup(array $_data = []) { $_data['site_id'] = $this->site_id; $_data['update_time'] = $_data['create_time'] = time(); $_db = Db::table($this->config['auth_group']); $insert_id = $_db->strict(false)->insertGetId($_data); ActionLog::getInstance()->write($_data, [], $_db->getLastSql()); return $insert_id; } /** * 修改系统用户角色组 * @param array $_data * @return int|string */ public function editGroup(array $_data = []) { $_data['site_id'] = $this->site_id; $_data['update_time'] = time(); $_db = Db::table($this->config['auth_group']); $affected = $_db->strict(false)->save($_data); ActionLog::getInstance()->write($_data, [], $_db->getLastSql()); return $affected; } /** * 更改用户角色组状态 * @param array $ids * @return int * @throws \think\db\exception\DbException */ public function statusGroup(string $ids = '', int $status = 1) { $_op = Db::table($this->config['auth_group']); $ids = explode(',', $ids); $_op->where('site_id', SITE_ID); $_op->where('id', 'in', $ids); $affected = $_op->update(['status' => $status]); ActionLog::getInstance()->write($ids, [], $_op->getLastSql()); return $affected; } /** * 删除系统用户角色组 * @param array $ids * @return int * @throws \think\db\exception\DbException */ public function deleteGroup($ids = []) { $_op = Db::table($this->config['auth_group']); $ids = explode(',', $ids); $_op->where('site_id', SITE_ID); $affected = $_op->where('id', 'in', $ids)->delete(); ActionLog::getInstance()->write($ids, [], $_op->getLastSql()); return $affected; } /** * 获得权限列表 * @param integer $uid 用户id * @param integer $type * @param integer $allfield 是否获取rule多字段,默认为false * @param integer $menu_type 0:获取菜单(默认) 1:获取按钮 2:获取所有 * @return array */ public function getAuthList($uid = 0, $type = [], $allfield = false, $menu_type = 0) { $uid = empty($uid) ? UID : $uid; 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->getUserGroups($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 = [ 'type' => $type, 'status' => 1, ]; $menu_type == 2 ? '' : $map['menu_type'] = $menu_type; //默认获取所有 config('app.app_debug') ?: $map['is_dev'] = 0;//开发者模式 //读取用户组所有权限规则 $_op = Db::table($this->config['auth_rule']); $_op->where($map)->where('id', 'in', $ids)->where('delete_time', null); $rules = $_op->order('sort DESC,create_time DESC')->select(); //$rules = Db::name($this->config['auth_rule'])->where($map)->field('condition,model_name')->select()->toArray(); //循环规则,判断结果。 $authList = []; // foreach ($rules as $rule) { if (!empty($rule['condition'])) { //根据condition进行验证 $user = $this->getUserInfo($uid); //获取用户信息,一维数组 $command = preg_replace('/\{(\w*?)\}/', '$user[\'\\1\']', $rule['condition']); //dump($command); //debug @(eval('$condition=(' . $command . ');')); if ($condition) { if ($allfield) { $rule['show'] = empty($rule['show']) ? false : true; //前端需要 $authList[] = $rule; } else { $authList[] = strtolower($rule['model_name']); } } } else { //只要存在就记录 if ($allfield) { $authList[] = $rule; } else { $authList[] = strtolower($rule['model_name']); } } } $_authList[$uid . $t] = $authList; if (2 == $this->config['auth_type']) { //规则列表结果保存到session //Session::set('_auth_list_' . $uid . $t, $authList); } return array_unique($authList, SORT_REGULAR); } /** * 获得用户资料,根据自己的情况读取数据库 */ protected function getUserInfo($uid) { static $userinfo = []; $user = Db::table($this->config['auth_user']); // 获取用户表主键 $_pk = is_string($user->getPk()) ? $user->getPk() : 'uid'; if (!isset($userinfo[$uid])) { $userinfo[$uid] = $user->where($_pk, $uid)->find(); } return $userinfo[$uid]; } }