CheckPermissionAttr.php 4.6 KB

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