Auth.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <?php
  2. namespace plugin\admin\api;
  3. use plugin\admin\app\model\Role;
  4. use plugin\admin\app\model\Rule;
  5. use support\exception\BusinessException;
  6. use function admin;
  7. /**
  8. * 对外提供的鉴权接口
  9. */
  10. class Auth
  11. {
  12. /**
  13. * 判断权限
  14. * 如果没有权限则抛出异常
  15. * @param string $controller
  16. * @param string $action
  17. * @return void
  18. * @throws \ReflectionException|BusinessException
  19. */
  20. public static function access(string $controller, string $action)
  21. {
  22. $code = 0;
  23. $msg = '';
  24. if (!static::canAccess($controller, $action, $code, $msg)) {
  25. throw new BusinessException($msg, $code);
  26. }
  27. }
  28. /**
  29. * 判断是否有权限
  30. * @param string $controller
  31. * @param string $action
  32. * @param int $code
  33. * @param string $msg
  34. * @return bool
  35. * @throws \ReflectionException|BusinessException
  36. */
  37. public static function canAccess(string $controller, string $action, int &$code = 0, string &$msg = ''): bool
  38. {
  39. // 无控制器信息说明是函数调用,函数不属于任何控制器,鉴权操作应该在函数内部完成。
  40. if (!$controller) {
  41. return true;
  42. }
  43. // 获取控制器鉴权信息
  44. $class = new \ReflectionClass($controller);
  45. $properties = $class->getDefaultProperties();
  46. $noNeedLogin = $properties['noNeedLogin'] ?? [];
  47. $noNeedAuth = $properties['noNeedAuth'] ?? [];
  48. // 不需要登录
  49. if (in_array($action, $noNeedLogin)) {
  50. return true;
  51. }
  52. // 获取登录信息
  53. $admin = admin();
  54. if (!$admin) {
  55. $msg = '请登录';
  56. // 401是未登录固定的返回码
  57. $code = 401;
  58. return false;
  59. }
  60. // 不需要鉴权
  61. if (in_array($action, $noNeedAuth)) {
  62. return true;
  63. }
  64. // 当前管理员无角色
  65. $roles = $admin['roles'];
  66. if (!$roles) {
  67. $msg = '无权限';
  68. $code = 2;
  69. return false;
  70. }
  71. // 角色没有规则
  72. $rules = Role::whereIn('id', $roles)->pluck('rules');
  73. $rule_ids = [];
  74. foreach ($rules as $rule_string) {
  75. if (!$rule_string) {
  76. continue;
  77. }
  78. $rule_ids = array_merge($rule_ids, explode(',', $rule_string));
  79. }
  80. if (!$rule_ids) {
  81. $msg = '无权限';
  82. $code = 2;
  83. return false;
  84. }
  85. // 超级管理员
  86. if (in_array('*', $rule_ids)){
  87. return true;
  88. }
  89. // 如果action为index,规则里有任意一个以$controller开头的权限即可
  90. if (strtolower($action) === 'index') {
  91. $rule = Rule::where(function ($query) use ($controller, $action) {
  92. $controller_like = str_replace('\\', '\\\\', $controller);
  93. $query->where('key', 'like', "$controller_like@%")->orWhere('key', $controller);
  94. })->whereIn('id', $rule_ids)->first();
  95. if ($rule) {
  96. return true;
  97. }
  98. $msg = '无权限';
  99. $code = 2;
  100. return false;
  101. }
  102. // 查询是否有当前控制器的规则
  103. $rule = Rule::where(function ($query) use ($controller, $action) {
  104. $query->where('key', "$controller@$action")->orWhere('key', $controller);
  105. })->whereIn('id', $rule_ids)->first();
  106. if (!$rule) {
  107. $msg = '无权限';
  108. $code = 2;
  109. return false;
  110. }
  111. return true;
  112. }
  113. }