ThinkPHP6授权降级策略分两层:中间件内权限校验失败时fallback至默认权限或轻量响应;菜单接口异常时返回静态JSON或备用路径,配合.env配置、fallback.php模板及管理接口实现动态开关与数据库/缓存失效保底。

ThinkPHP6 添加授权降级策略,核心是把“权限不可用时还能基本可用”这件事拆成两层来处理:一是授权校验本身要能失败兜底,二是被授权保护的接口要能降级响应。不追求强一致,重在高并发或依赖故障时系统不雪崩。
中间件里做可降级的权限判断
别在控制器里写 if(Auth::check()),而是在自定义鉴权中间件(如 AuthMiddleware)中封装带降级逻辑的校验:
- 先尝试从 Redis 或本地缓存读取用户角色/权限规则(比如 cache('auth_rules_'.$uid)),命中则直接校验
- 若缓存未命中或查库超时(Db::table('role_permission')->where(...)->select() 加 timeout=0.5),自动 fallback 到预设的默认权限集(如 ['view_dashboard', 'read_user'])
- 若连默认权限都加载失败,返回一个轻量 Response:json(['code'=>200, 'msg'=>'权限服务暂不可用', 'data'=>['has_access'=>false]]),而不是抛异常或 500
路由与菜单层面的兼容性降级
前端菜单和按钮权限常依赖后端返回的菜单树,一旦权限服务异常,整个左侧导航可能空白。解决方法是:
- 菜单接口(如 GET /api/menu)加一层降级开关:检查 cache('fallback:menu') 是否为 true,是则直接返回静态 JSON 文件内容(如 config/fallback_menu.json)
- AuthRule 表中 type='menu' 的记录,加字段 fallback_path 存备用路径(如 /dashboard/default),权限失效时跳转该页面而非报错
- 前端请求菜单时带上 ?v=20260826 参数,后端根据该参数决定是否绕过实时权限计算,直接走缓存快照
配置驱动的全局降级开关
不用改代码就能快速开启/关闭降级,靠的是统一配置入口:
立即学习“PHP免费学习笔记(深入)”;
- 在 .env 中加 FALLBACK_AUTH=true,所有中间件统一读取 Env::get('FALLBACK_AUTH', false)
- 新建 config/fallback.php,定义各类降级响应模板:
'auth_fail' => ['code'=>200, 'msg'=>'当前功能权限校验中,请稍候再试', 'data'=>[]],
'menu_empty' => ['menus'=>[['title'=>'首页','href'=>'/dashboard']]] - 后台提供管理接口 POST /admin/fallback/auth?enable=1,调用 Cache::set('fallback:auth', true, 3600) 即刻生效
数据库与缓存失效时的保底策略
权限数据通常存在 MySQL + Redis 组合中,任一环节挂掉都会导致鉴权中断。需提前设计退路:
- DB 查询权限时,用 try/catch 包裹,并设置 PDO 层 timeout;捕获 PDOException 后,立即读取本地文件 config/permissions_fallback.php 作为兜底规则
- Redis 不可用时,将权限校验临时切换为 session 内存模式:$rules = $request->session()->get('cached_auth_rules', []);
- 强制所有权限检查最终 fallback 到一个硬编码白名单(如仅允许访问 /index/welcome、/user/profile),避免全站 403



















