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.
user_center/app/Services/Authenticate.php

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;
}
}