OperationsAdminMiddleware.php 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. namespace App\Http\Middleware;
  3. use Closure;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Support\Facades\DB;
  6. /**
  7. * 运营配置类接口(维护、支付配置、APP 配置、分享赚钱、报表设置与对账、模拟数据重置等)的准入。
  8. *
  9. * 超级管理员(ID 1)直接放行。其他管理员只查数据库角色,不用环境变量白名单:
  10. * 1. 角色勾选了这个接口的按钮 URI(路由 defaults 的 permission_uri,没有则为路由 URI,同 CheckButtonPermission)→ 放行;
  11. * 2. 这个按钮在菜单里已经建了但角色没勾 → 拒绝;
  12. * 3. 按钮还没建时,角色勾选了同一模块的任意按钮(admin/<模块> 或 admin/<模块>/...,如 admin/maintenance/logs 属于 admin/maintenance)→ 放行。
  13. * 所以没有单独建按钮的接口,跟随同模块的授权,不会因漏建按钮而对所有人开放,也不需要逐个建按钮。
  14. */
  15. class OperationsAdminMiddleware
  16. {
  17. private const SUPER_ADMIN_ID = 1;
  18. public function handle(Request $request, Closure $next)
  19. {
  20. $adminId = (int) ($request->user->id ?? 0);
  21. $route = $request->route();
  22. $uri = $route ? ($route->defaults['permission_uri'] ?? ltrim($route->uri(), '/')) : '';
  23. if (!self::allowed($adminId, $uri)) {
  24. return response()->json([
  25. 'code' => -1,
  26. 'timestamp' => time(),
  27. 'msg' => '无运营配置管理权限',
  28. 'data' => [],
  29. ]);
  30. }
  31. return $next($request);
  32. }
  33. public static function allowed(int $adminId, string $uri): bool
  34. {
  35. if ($adminId <= 0) return false;
  36. if ($adminId === self::SUPER_ADMIN_ID) return true;
  37. if ($uri === '') return false;
  38. $granted = static fn () => DB::table('role_user as ru')
  39. ->join('role_menu as rm', 'rm.role_id', '=', 'ru.role_id')
  40. ->join('menus as m', 'm.id', '=', 'rm.menu_id')
  41. ->where('ru.user_id', $adminId);
  42. if ($granted()->where('m.uri', $uri)->exists()) return true;
  43. if (DB::table('menus')->where('uri', $uri)->exists()) return false;
  44. $module = implode('/', array_slice(explode('/', $uri), 0, 2));
  45. return $granted()->where(static fn ($q) => $q->where('m.uri', $module)->orWhere('m.uri', 'like', $module . '/%'))->exists();
  46. }
  47. }