webman/plugin/admin/api/Auth.php

127 lines
3.6 KiB
PHP
Raw Normal View History

2025-02-15 12:13:10 +08:00
<?php
namespace plugin\admin\api;
use plugin\admin\app\model\Role;
use plugin\admin\app\model\Rule;
use support\exception\BusinessException;
use function admin;
/**
* 对外提供的鉴权接口
*/
class Auth
{
/**
* 判断权限
* 如果没有权限则抛出异常
* @param string $controller
* @param string $action
* @return void
* @throws \ReflectionException|BusinessException
*/
public static function access(string $controller, string $action)
{
$code = 0;
$msg = '';
if (!static::canAccess($controller, $action, $code, $msg)) {
throw new BusinessException($msg, $code);
}
}
/**
* 判断是否有权限
* @param string $controller
* @param string $action
* @param int $code
* @param string $msg
* @return bool
* @throws \ReflectionException|BusinessException
*/
public static function canAccess(string $controller, string $action, int &$code = 0, string &$msg = ''): bool
{
// 无控制器信息说明是函数调用,函数不属于任何控制器,鉴权操作应该在函数内部完成。
if (!$controller) {
return true;
}
// 获取控制器鉴权信息
$class = new \ReflectionClass($controller);
$properties = $class->getDefaultProperties();
$noNeedLogin = $properties['noNeedLogin'] ?? [];
$noNeedAuth = $properties['noNeedAuth'] ?? [];
// 不需要登录
if (in_array($action, $noNeedLogin)) {
return true;
}
// 获取登录信息
$admin = admin();
if (!$admin) {
$msg = '请登录';
// 401是未登录固定的返回码
$code = 401;
return false;
}
// 不需要鉴权
if (in_array($action, $noNeedAuth)) {
return true;
}
// 当前管理员无角色
$roles = $admin['roles'];
if (!$roles) {
$msg = '无权限';
$code = 2;
return false;
}
// 角色没有规则
$rules = Role::whereIn('id', $roles)->pluck('rules');
$rule_ids = [];
foreach ($rules as $rule_string) {
if (!$rule_string) {
continue;
}
$rule_ids = array_merge($rule_ids, explode(',', $rule_string));
}
if (!$rule_ids) {
$msg = '无权限';
$code = 2;
return false;
}
// 超级管理员
if (in_array('*', $rule_ids)){
return true;
}
// 如果action为index规则里有任意一个以$controller开头的权限即可
if (strtolower($action) === 'index') {
$rule = Rule::where(function ($query) use ($controller, $action) {
$controller_like = str_replace('\\', '\\\\', $controller);
$query->where('key', 'like', "$controller_like@%")->orWhere('key', $controller);
})->whereIn('id', $rule_ids)->first();
if ($rule) {
return true;
}
$msg = '无权限';
$code = 2;
return false;
}
// 查询是否有当前控制器的规则
$rule = Rule::where(function ($query) use ($controller, $action) {
$query->where('key', "$controller@$action")->orWhere('key', $controller);
})->whereIn('id', $rule_ids)->first();
if (!$rule) {
$msg = '无权限';
$code = 2;
return false;
}
return true;
}
}