| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 | <?phpnamespace app\admin\middleware;use app\admin\attr\Permission;use app\common\exception\CatchException;use app\common\model\Admin;use app\common\model\Role;use think\Request;class CheckPermissionAttr{    public function handle(Request $request, \Closure $next)    {        // 通过依赖注入获取admin        $admin = app(Admin::class);        $role = $admin->role;        $codes = $role->codes;        if (!$role->valid) {            throw new CatchException("角色‘{$role->name}’已被禁用,如有疑问,请联系管理员", 403);        }        // 超级管理员可以做任何事        if (in_array(Role::CODE_SUPER_ADMIN, $codes)) {            return $next($request);        }        // 获取权限注解        $controller = $request->controller();        $controllerNameSpace = 'app\\admin\\controller\\' . $controller;        $ref = new \ReflectionClass($controllerNameSpace);        $attrs = $ref->getAttributes(Permission::class);        $methodName = $request->action();        $method = $ref->getMethod($methodName);        $methodAttrs = $method->getAttributes(Permission::class);        // 如果有具体的方法权限        if ($methodAttrs) {            foreach ($methodAttrs as $attrRaw) {                /**                 * @var Permission                 */                $attr = $attrRaw->newInstance();                // 忽略权限要求                if ($attr->ignore) {                    return $next($request);                }                /*                 * 权限值设置                 */                $permission = $attr->value;                // 继承权限                if ($attr->inherit) {                    if (count($attrs) > 1) {                        throw new \InvalidArgumentException('使用了继承权限值,但是controller的权限Attribute不止一个');                    }                    $controllerAttr = $attrs[0]->newInstance();                    $controllerPermission = $controllerAttr->value;                    // 是否使用控制器名                    // 尽管在方法上没有权限Attr的话,不会进入foreach循环中,但是还是有可能传一个空的permission进来                    if (!$permission) {                        if ($controllerAttr->useMethodName) {                            $permission = "$controllerPermission.$methodName";                        } else {                            $permission = $controllerPermission;                        }                    }                } else {                    // 不继承权限,直接使用$permission, 但是检查权限值是否为空                    if (!$permission) {                        if (count($attrs) > 1) {                            throw new \InvalidArgumentException('没有使用继承,而且权限值为空,尝试使用controller权限值规则,但是controller的权限Attribute不止一个');                        }                        $controllerAttr = $attrs[0]->newInstance();                        $controllerPermission = $controllerAttr->value;                        // 使用控制器attr规则                        // 使用方法名                        if ($controllerAttr->useMethodName) {                            $permission = $methodName;                        } else {                            // 使用控制器名                            $permission = strtolower($controller);                        }                    }                    // 直接使用$permission                }                /*                * 检查权限                */                if (!in_array($permission, $codes)) {                    throw new CatchException("未具有权限$permission, 禁止访问", 403);                }                // 成功                return $next($request);            }        }        // 只有控制器权限        /**         * @var \ReflectionAttribute $attrRaw          */        foreach ($attrs as $attrRaw) {            /**             * @var Permission             */            $attr = $attrRaw->newInstance();            $permission = $attr->value;            // 自动使用方法名作为权限值            if ($attr->useMethodName) {                $permission = "$permission.$methodName";            } elseif (!$permission) {                // 没有标注要什么权限而且useMethodName设为了false,使用controller的小写作为权限值                $permission = strtolower($controller);            }            if (!in_array($permission, $codes)) {                throw new CatchException("未具有权限$permission, 禁止访问", 403);            }        }        return $next($request);    }}
 |