主题
Are you an LLM? You can read better optimized documentation at /server/permission.md for this page in Markdown format
RBAC 权限系统
CatchAdmin 专业版采用标准的 RBAC(基于角色的访问控制)权限模型,实现用户-角色-权限的多对多关联关系。如需深入了解 RBAC 权限机制,可参考这篇基于角色的访问控制文档。
基本约定
- 超级管理员不受任何权限控制
- 对于 RBAC 权限控制,
GET请求默认放行,不受权限限制
权限模块
CatchAdmin 专业版默认不启用权限模块和动态菜单功能。使用前需要先激活权限模块
php
php artisan catch:module:install permissionsTIP
开启之后如果没有权限菜单,可以刷新一下
中间件
权限模块提供专用的权限验证中间件,实现访问控制功能
php
use Catch\Exceptions\FailedException;
use Catch\Facade\Admin;
use Catch\Support\Permission\PermissionExemptionResolver;
use Closure;
use Illuminate\Http\Request;
use Modules\Permissions\Exceptions\PermissionForbidden;
use Modules\User\Models\User;
class PermissionGate
{
public function handle(Request $request, Closure $next): mixed
{
if ($this->isAllowGetRequest($request)) {
return $next($request);
}
if (config('app.env') == 'demo') {
throw new FailedException('演示环境禁止操作');
}
if (app(PermissionExemptionResolver::class)->isExempt($request)) {
return $next($request);
}
/* @var User $user */
$user = Admin::auth();
if (! $user->can()) {
throw new PermissionForbidden;
}
return $next($request);
}
protected function isAllowGetRequest(Request $request): bool
{
return config('catch.request_allowed') && $request->isMethod('get');
}
}PermissionExempt 属性
从当前版本开始,权限系统支持通过 PHP Attribute 显式声明某个控制器或某个控制器方法跳过 RBAC 校验。
属性类:
php
namespace Catch\Attributes;
use Attribute;
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]
class PermissionExempt
{
public function __construct(
public readonly string|array|null $methods = null
) {
}
}使用场景
- 第三方回调接口
- 内部桥接接口
- 只需要登录态,不参与角色权限分配的接口
基本用法
作用于方法:
php
use Catch\Attributes\PermissionExempt;
class PayNotifyController
{
#[PermissionExempt]
public function callback()
{
}
}按 HTTP Method 生效:
php
use Catch\Attributes\PermissionExempt;
class OpenapiController
{
#[PermissionExempt('POST')]
public function notify()
{
}
#[PermissionExempt(['GET', 'POST'])]
public function sync()
{
}
}作用于整个控制器:
php
use Catch\Attributes\PermissionExempt;
#[PermissionExempt]
class WebhookController
{
public function store()
{
}
public function update()
{
}
}参数说明
null:当前类或方法的全部请求方法都跳过 RBAC 校验string:只匹配一个请求方法,例如POSTarray:匹配多个请求方法,例如['GET', 'POST']
系统会统一把请求方法转成大写后再进行匹配。
优先级
方法上的 PermissionExempt 优先级高于控制器类上的 PermissionExempt。
例如:
php
use Catch\Attributes\PermissionExempt;
#[PermissionExempt]
class DemoController
{
#[PermissionExempt('POST')]
public function callback()
{
}
}这里 callback() 只会在 POST 请求时跳过 RBAC 校验,GET 请求会继续进入正常权限判断。
生效边界
PermissionExempt影响的是 RBAC 权限校验- 登录认证中间件依然生效
demo环境写请求保护依然生效GET默认放行规则依然生效
这意味着接口即使声明了 PermissionExempt,依然需要先通过认证链路。demo 环境下的写请求依然会被拦截。
权限配置
了解中间件机制后,重点需要掌握权限的数据结构组成。前后端分离项目的权限配置相比传统渲染项目更为复杂,建议先熟悉 Vue 路由相关知识。在权限管理/菜单管理页面点击新增,可看到权限配置界面

CatchAdmin 将权限分为三种类型
目录 目录仅仅就是一级菜单
菜单 菜单就是主要的页面
按钮 每个页面的操作,每个按钮都对应后端的控制的一个
action,这个非常重要路由
Path对应前端vue路由的path组件 对应前端
vue路由的component- 目录类型一般都是选择 Layout 组件
- 菜单类型则是选择对应页面的组件
传统 Laravel 项目通过 Controller 实现页面和操作的权限控制。前后端分离项目中,页面渲染交由前端处理,但数据操作仍由后端控制,因此 RBAC 权限系统主要负责 API 访问控制。后端重点关注按钮类型权限,即对控制器 action 方法的访问控制。 因此需要为控制器的每个 action 操作配置相应的权限标识,实现精细化权限控制。
权限判断
CatchAdmin 专业版采用模块化架构,权限标识格式规范如下
module@controller@action例如权限模块的角色列表操作,权限验证标识格式示例
php
Modules\permissions\Http\Controller\RolesController@index当前用户是否有权限
php
// 验证当前用户是否具有指定权限
Auth::user()->can(string $permission = null);- permission 参数格式为
module@controller@action,例如permissions@Roles@index
用户的权限
php
// 获取用户的所有权限列表
/*@var Model\Roles $user*/
$user->withPermissions()->permissions;角色权限
php
/*@var Model\Roles $role*/
$role->getPermissions()