CheckPermissionAttr.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. namespace app\admin\middleware;
  3. use app\admin\attr\Permission;
  4. use app\common\exception\CatchException;
  5. use app\common\model\Admin;
  6. use app\common\model\Role;
  7. use think\Request;
  8. class CheckPermissionAttr
  9. {
  10. public function handle(Request $request, \Closure $next)
  11. {
  12. // 通过依赖注入获取admin
  13. $admin = app(Admin::class);
  14. $role = $admin->role;
  15. $codes = $role->codes;
  16. if (!$role->valid) {
  17. throw new CatchException("角色‘{$role->name}’已被禁用,如有疑问,请联系管理员", 403);
  18. }
  19. // 超级管理员可以做任何事
  20. if (in_array(Role::CODE_SUPER_ADMIN, $codes)) {
  21. return $next($request);
  22. }
  23. // 获取权限注解
  24. $controller = $request->controller();
  25. $controllerNameSpace = 'app\\admin\\controller\\' . $controller;
  26. $ref = new \ReflectionClass($controllerNameSpace);
  27. $attrs = $ref->getAttributes(Permission::class);
  28. $methodName = $request->action();
  29. $method = $ref->getMethod($methodName);
  30. $methodAttrs = $method->getAttributes(Permission::class);
  31. // 如果有具体的方法权限
  32. if ($methodAttrs) {
  33. foreach ($methodAttrs as $attrRaw) {
  34. /**
  35. * @var Permission
  36. */
  37. $attr = $attrRaw->newInstance();
  38. // 忽略权限要求
  39. if ($attr->ignore) {
  40. return $next($request);
  41. }
  42. /*
  43. * 权限值设置
  44. */
  45. $permission = $attr->value;
  46. // 继承权限
  47. if ($attr->inherit) {
  48. if (count($attrs) > 1) {
  49. throw new \InvalidArgumentException('使用了继承权限值,但是controller的权限Attribute不止一个');
  50. }
  51. $controllerAttr = $attrs[0]->newInstance();
  52. $controllerPermission = $controllerAttr->value;
  53. // 是否使用控制器名
  54. // 尽管在方法上没有权限Attr的话,不会进入foreach循环中,但是还是有可能传一个空的permission进来
  55. if (!$permission) {
  56. if ($controllerAttr->useMethodName) {
  57. $permission = "$controllerPermission.$methodName";
  58. } else {
  59. $permission = $controllerPermission;
  60. }
  61. }
  62. } else {
  63. // 不继承权限,直接使用$permission, 但是检查权限值是否为空
  64. if (!$permission) {
  65. if (count($attrs) > 1) {
  66. throw new \InvalidArgumentException('没有使用继承,而且权限值为空,尝试使用controller权限值规则,但是controller的权限Attribute不止一个');
  67. }
  68. $controllerAttr = $attrs[0]->newInstance();
  69. $controllerPermission = $controllerAttr->value;
  70. // 使用控制器attr规则
  71. // 使用方法名
  72. if ($controllerAttr->useMethodName) {
  73. $permission = $methodName;
  74. } else {
  75. // 使用控制器名
  76. $permission = strtolower($controller);
  77. }
  78. }
  79. // 直接使用$permission
  80. }
  81. /*
  82. * 检查权限
  83. */
  84. if (!in_array($permission, $codes)) {
  85. throw new CatchException("未具有权限$permission, 禁止访问", 403);
  86. }
  87. // 成功
  88. return $next($request);
  89. }
  90. }
  91. // 只有控制器权限
  92. /**
  93. * @var \ReflectionAttribute $attrRaw
  94. */
  95. foreach ($attrs as $attrRaw) {
  96. /**
  97. * @var Permission
  98. */
  99. $attr = $attrRaw->newInstance();
  100. $permission = $attr->value;
  101. // 自动使用方法名作为权限值
  102. if ($attr->useMethodName) {
  103. $permission = "$permission.$methodName";
  104. } elseif (!$permission) {
  105. // 没有标注要什么权限而且useMethodName设为了false,使用controller的小写作为权限值
  106. $permission = strtolower($controller);
  107. }
  108. if (!in_array($permission, $codes)) {
  109. throw new CatchException("未具有权限$permission, 禁止访问", 403);
  110. }
  111. }
  112. return $next($request);
  113. }
  114. }