123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- <?php
- namespace 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);
- }
- }
|