123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- <?php
- namespace App\Http\Middleware;
- use Closure;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\DB;
- class AdminAuth
- {
- // 无需验证的路径
- protected $except = [
- 'admin/login/index',
- 'admin/login/send_code',
- 'admin/login/out',
- 'admin/files_manager/add', // 文件上传
- 'admin/contact_way/part_user', // 接待人员
- 'admin/product/get_spec_html', // 获取类型下的规格
- ];
- //默认配置
- protected $_config = [
- 'auth_on' => true, // 认证开关
- 'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
- 'auth_group' => 'auth_group', // 用户组数据表名
- 'auth_group_access' => 'auth_group_access', // 用户-用户组关系表
- 'auth_rule' => 'auth_rule' // 权限规则表
- ];
- /**
- * $prefix表前缀
- */
- public function __construct()
- {
- // 判断配置
- if ( config('AUTH_CONFIG') ) {
- //可设置配置项 AUTH_CONFIG, 此配置项为数组。
- $this->_config = array_merge($this->_config, config('AUTH_CONFIG'));
- }
- }
- /**
- * Handle an incoming request.
- *
- * @param \Illuminate\Http\Request $request
- * @param \Closure $next
- * @return mixed
- */
- public function handle(Request $request, Closure $next)
- {
- // 当前路径
- $path = ltrim($request->getPathInfo(), '/');
- // 判断是否需要验证登录
- if (!in_array($path, $this->except)) {
- // 如果没有登录,重定向到登录页
- if ( !admin('uid')) $this->unLogin($request);
- // 如果不是超级管理员
- if ( !in_array(admin('uid'), explode(',', config('administrator'))) ) {
- // 进行验证
- if ( !$this->check($path, admin('uid')) ) $this->noAuth('没有权限!');
- }
- }
- // 追加入
- $request['authRules'] = $this->getAuthList(admin('uid'),1);
- // 返回下一个闭包
- return $next($request);
- }
- /**
- * Handle an unauthenticated user.
- *
- * @param \Illuminate\Http\Request $request
- * @return void
- *
- * @throws AdminAuthException
- */
- protected function unLogin($request)
- {
- throw new \App\Exceptions\Admin\AuthException('请先登录',$this->redirectTo($request),0);
- }
- /**
- * Handle an unauthenticated user.
- *
- * @param \Illuminate\Http\Request $request
- * @return void
- *
- * @throws AdminAuthException
- */
- protected function noAuth($msg,$url='',$wait=3)
- {
- throw new \App\Exceptions\Admin\AuthException($msg,$url,$wait);
- }
- /**
- * Get the path the user should be redirected to when they are not authenticated.
- *
- * @param \Illuminate\Http\Request $request
- * @return string|null
- */
- protected function redirectTo($request)
- {
- if (!$request->expectsJson()) return route('login');
- }
- /**
- * 检查权限
- * @param name string|array 需要验证的规则列表
- * @param uid int 认证用户的id
- * @return boolean 通过验证返回true;失败返回false
- */
- public function check($path, $uid, $type = 1)
- {
- // 未开启验证,直接通过
- if ( !$this->_config['auth_on'] ) return true;
- // 获取用户需要验证的所有有效规则列表
- $authList = $this->getAuthList($uid, $type);
-
- // 切割path
- $path = explode('/', $path);
- // 没有控制器
- if( count($path) < 2 ) $path[] = 'index';
- // 没有方法
- if( count($path) < 3 ) $path[] = 'index';
- // 切割path
- $path = implode('/', $path);
- // 判断是否通过验证
- return in_array($path, $authList);
- }
- /**
- * 根据用户id获取用户组,返回值为数组
- * @param int $uid 用户id
- * @return array 用户所属的用户组
- */
- public function getGroups($uid)
- {
- // 用户组
- static $groups = [];
- // 存在小组,返回
- if ( isset($groups[$uid]) ) return $groups[$uid];
- // 从数据库查询
- $userrGroups = DB::table($this->_config['auth_group_access'])
- ->where([[$this->_config['auth_group_access'].'.user_uid','=',$uid],[$this->_config['auth_group'].'.status','=',1]])
- ->join( $this->_config['auth_group'], $this->_config['auth_group_access'].'.group_id','=',$this->_config['auth_group'].'.id')
- ->select(['user_uid as uid','group_id','title','rules'])->get()->toArray();
- // 获取对应用户的权限组
- $groups[$uid] = $userrGroups ?: [];
- // 返回用户的权限组
- return $groups[$uid];
- }
- /**
- * 获得权限列表
- * @param integer $uid 用户id
- * @param integer $type
- */
- protected function getAuthList($uid, $type)
- {
-
- // 保存用户验证通过的权限列表
- static $_authList = [];
- // 验证类型
- $key = $uid .'_t_'.implode(',', (array) $type);
- // 已经存在权限列表,直接返回
- if (isset($_authList[$key])) return $_authList[$key];
- // 验证类型,如果不是实时验证
- if ( $this->_config['auth_type'] == 2 ) {
- // 从session读取验证列表
- $session = session('_AUTH_LIST_'.$key);
- // 存在则返回
- if( !empty($session) ) return $session;
- }
- // 读取用户所属用户组
- $groups = $this->getGroups($uid);
- // 保存用户所属用户组设置的所有权限规则id
- $ids = [];
- // 获取字段值
- $ids = array_column($groups,'rules');
- // 合并字符值
- $ids = array_unique(array_filter(explode(',',implode(',',$ids))));
- // 为空
- if( empty($ids) ) return [];
- // 读取用户组所有权限规则
- $rules = Db::table($this->_config['auth_rule'])->whereIn('menu_id',$ids)->pluck('name')->toArray();
- // 循环转大写
- foreach ( $rules as $rule ) {
- // 转小写,截除左边斜杠
- $rules[] = ltrim(strtolower($rule),'/');
- }
- // 去重
- $rules = array_unique($rules);
- // 如果是登录验证
- if ($this->_config['auth_type'] == 2 ) {
- // 用户验证列表
- $rules[$key] = $rules;
- //规则列表结果保存到session
- session('_AUTH_LIST_'.$key,$rules);
- }
- // 返回结果
- return $rules;
- }
- }
|