You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
4.2 KiB
118 lines
4.2 KiB
4 years ago
|
<?php
|
||
|
|
||
|
|
||
|
namespace App\Services;
|
||
|
|
||
|
use Closure;
|
||
|
use Illuminate\Contracts\Auth\Factory as Auth;
|
||
|
use Illuminate\Support\Facades\Cache;
|
||
|
use Illuminate\Support\Facades\DB;
|
||
|
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||
|
use phpDocumentor\Reflection\Types\Self_;
|
||
|
|
||
|
/**
|
||
|
* @title 权限认证类
|
||
|
* @description
|
||
|
* 功能特性:
|
||
|
* 1,是对规则进行认证,不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。
|
||
|
* $auth=new Auth(); $auth->check('规则名称','用户id')
|
||
|
* 2,可以同时对多条规则进行认证,并设置多条规则的关系(or或者and)
|
||
|
* $auth=new Auth(); $auth->check('规则1,规则2','用户id','and')
|
||
|
* 第三个参数为and时表示,用户需要同时具有规则1和规则2的权限。 当第三个参数为or时,表示用户值需要具备其中一个条件即可。默认为or
|
||
|
* 3,一个用户可以属于多个用户组(think_auth_group_access表 定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group 定义了用户组权限)
|
||
|
* 4,支持规则表达式。
|
||
|
* @package App\Service
|
||
|
* @author zcstatham
|
||
|
* @time 2021/1/25
|
||
|
*/
|
||
|
class Authenticate extends Middleware
|
||
|
{
|
||
|
|
||
|
//默认配置
|
||
|
protected $_config = array(
|
||
|
'auth_on' => true, // 认证开关
|
||
|
'auth_type' => 1, // 认证方式,1为实时认证;2为登录认证。
|
||
|
'auth_group' => 'uc_employee_group_t', // 用户组数据表名
|
||
|
'auth_rule' => 'uc_auth_rule_t', // 权限规则表
|
||
|
'auth_user' => 'uc_employee_t' // 用户信息表
|
||
|
);
|
||
|
|
||
|
public function __construct(Auth $auth)
|
||
|
{
|
||
|
parent::__construct($auth);
|
||
|
$this->_config = array_merge($this->_config, config('auth.conf'));
|
||
|
}
|
||
|
|
||
|
public function handle($request, Closure $next, ...$guards)
|
||
|
{
|
||
|
// 登录验证
|
||
|
if (!$this->auth->guard('api')->check()) {
|
||
|
return response()->json(['code' => 401, 'msg' => '用户未登录'], 401);
|
||
|
}
|
||
|
$url ='';
|
||
|
$route = $request->route();
|
||
|
preg_match('/Controllers.(\w+).\w+@\w+/', $route->getActionName(), $match);
|
||
|
foreach ($route->methods() as $method){
|
||
|
$url .= $match[1] . '_' . $method .'_'. $route->uri() . ',';
|
||
|
}
|
||
|
// 权限验证
|
||
|
if (!$this->check($url, $this->auth)) {
|
||
|
return response()->json(['code' => 403, 'msg' => '用户未授权访问'], 403);
|
||
|
}
|
||
|
return $next($request);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @title 检查权限
|
||
|
* @description check
|
||
|
* @param $name
|
||
|
* @param $auth
|
||
|
* @param string $mode
|
||
|
* @param string $relation
|
||
|
* @return bool
|
||
|
* @author zcstatham
|
||
|
* @time 2021/1/25
|
||
|
*/
|
||
|
public function check($name, $auth, $mode = 'url', $relation = 'or')
|
||
|
{
|
||
|
$user = $auth->user();
|
||
|
if (!$this->_config['auth_on']) {
|
||
|
return true;
|
||
|
}
|
||
|
if ($user['id'] == 1) {
|
||
|
return true;
|
||
|
}
|
||
|
$authList = $auth->payload()->get('auth_list');
|
||
|
if (is_string($name)) {
|
||
|
$name = strtolower($name);
|
||
|
if (strpos($name, ',') !== false) {
|
||
|
$name = explode(',', $name);
|
||
|
} else {
|
||
|
$name = array($name);
|
||
|
}
|
||
|
}
|
||
|
$list = array(); //保存验证通过的规则名
|
||
|
foreach ($authList as $auth) {
|
||
|
$query = preg_replace('/^.+\?/U', '', $auth);
|
||
|
if ($mode == 'url' && $query != $auth) {
|
||
|
parse_str($query, $param); //解析规则中的param
|
||
|
$intersect = array_intersect_assoc(request()->param(), $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 ($relation == 'or' and !empty($list)) {
|
||
|
return true;
|
||
|
}
|
||
|
$diff = array_diff($name, $list);
|
||
|
if ($relation == 'and' and empty($diff)) {
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
}
|