ThinkPHP插件权限控制必须强制路由走主系统RBAC中间件,禁止插件目录直接暴露;插件路由需在app/middleware.php中显式绑定'plugin'=>['rbac'],并用Route::group('plugin')->middleware('rbac')声明;安装与启用阶段须硬编码校验或钩子注入权限;配置页面和API接口均需前后端双重校验及租户隔离。

ThinkPHP插件权限控制必须防止第三方插件绕过主系统权限校验,避免未授权访问后台接口、读取敏感配置或执行危险操作。插件目录若直接暴露在webroot下且无路由拦截,攻击者可构造路径直接访问Plugin/XXX/Controller/Install.php触发安装逻辑。
插件路由必须强制走主系统权限中间件
在app/middleware.php中为插件路由分组显式绑定rbac中间件,不能依赖全局中间件注册。
打开app/middleware.php,在'plugin' => [...]数组中写入['rbac'],确保该键名与路由分组名严格一致。
定义插件路由时使用Route::group('plugin', function () { ... })->middleware('rbac'),【middleware()必须紧跟group()调用,不能写在闭包内部】。
立即学习“PHP免费学习笔记(深入)”;
插件控制器方法名不得与主系统冲突,例如禁止命名为index、login、logout——这些名称可能被rbac中间件误判为白名单路径而放行。
插件安装与启用阶段的权限熔断
方法一:安装入口硬编码校验
在插件根目录的Install.php中,第一行插入session('admin_id') !== null && Auth::check(session('admin_id'), 'plugin.install'),不通过直接exit('no permission')。
方法二:启用钩子注入权限判断
在插件config.php中声明hook事件,如'addon_enable',在对应Hook类的handle方法开头调用Auth::check($uid, 'plugin.enable'),返回false则throw new HttpException(403)。
注意:插件启用后生成的路由规则必须写入auth_rule表,type=2,status=1,name字段格式为plugin/xxx/enable,【name值必须和实际访问URL路径完全一致,含斜杠方向与末尾斜杠】。
插件配置页面的按钮级权限隔离
第一步:在插件视图模板中,用{:Auth::check(session('admin_id'), 'plugin.xxx.config.edit')}包裹编辑按钮HTML。
第二步:在插件控制器的configSave方法顶部,再次执行相同权限校验,失败则$this->error('权限不足')。
第三步:校验通过后,立即用Db::name('plugin_config')->where('addon', 'xxx')->update()更新配置,【禁止将用户提交的raw_input直接入库,必须经过Validate验证器过滤】。
这一步操作起来很简单,直接把文件拖进去就行。
插件API接口的无状态权限校验
插件提供的/api/xxx接口,必须弃用Auth::check(),改从JWT payload读取permissions数组。
在插件中间件中解析Authorization头,用JWT::decode($token, new Key(config('jwt.secret'), 'HS256'))获取payload。
检查payload['permissions']是否包含plugin.xxx.api.read,不包含则return json(['code'=>403], 403)。
数据库查询必须加租户隔离条件,例如where('addon', 'xxx')->where('tenant_id', $payload['tenant_id']),防止跨租户数据泄露。



















