外观
Foundation/Rbac 使用指南
架构概览
Foundation/Rbac/
├── Contracts/ # 接口定义
│ ├── PermissionChecker.php
│ ├── PermissionResolver.php
│ └── MenuVisibilityChecker.php
├── Resolvers/ # 策略实现(可切换)
│ ├── SnapshotPermissionResolver.php # V1: 读快照
│ └── RoleBasedPermissionResolver.php # V2: 读角色
├── Checkers/ # 检查器实现
│ ├── DatabasePermissionChecker.php
│ └── DatabaseMenuVisibilityChecker.php
├── Concerns/ # Trait 混入
│ └── HasLimsPermissions.php
├── Middleware/
│ └── PermissionMiddleware.php
├── Facades/
│ └── LimsRbac.php
├── LimsRbac.php # 核心服务
└── LimsRbacServiceProvider.php1. 在 User Model 中使用 Trait
php
<?php
namespace App\Models;
use App\Foundation\Rbac\Concerns\HasLimsPermissions;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasLimsPermissions;
}现在 User Model 自动获得权限方法:
php
$user = User::find(1);
// 检查权限
$user->hasPermission('sample.add');
$user->hasAnyPermission(['sample.add', 'sample.edit']);
$user->hasAllPermissions(['sample.add', 'sample.edit']);
// 检查菜单
$user->canViewMenu(123);
$user->getVisibleMenus();
// 检查超管
$user->isSuperAdmin();
// 清除缓存
$user->clearPermissionCache();2. 使用 Facade(推荐)
php
use App\Foundation\Rbac\Facades\LimsRbac;
// 检查当前用户权限
LimsRbac::check('sample.add');
LimsRbac::check(['sample.add', 'sample.edit']); // OR
LimsRbac::check(['sample.add', 'sample.edit'], true); // AND
// 检查指定用户权限
LimsRbac::userCan($userId, 'sample.add');
LimsRbac::userCan($user, 'sample.add');
// 检查菜单
LimsRbac::canViewMenu(123);
LimsRbac::userCanViewMenu($userId, 123);
LimsRbac::getVisibleMenus();
// 检查超管
LimsRbac::isSuperAdmin();
// 批量检查
$results = LimsRbac::batchCheck(['sample.add', 'sample.edit', 'sample.delete']);
// ['sample.add' => true, 'sample.edit' => false, 'sample.delete' => false]3. 路由中间件
php
use Illuminate\Support\Facades\Route;
// 单个权限
Route::get('/sample', [SampleController::class, 'index'])
->middleware('lims.permission:sample.view');
// 多个权限(OR)- 使用分号分隔
Route::post('/sample', [SampleController::class, 'store'])
->middleware('lims.permission:sample.add;sample.edit');
// 多个权限(AND)- 最后加 ;and
Route::delete('/sample/{id}', [SampleController::class, 'destroy'])
->middleware('lims.permission:sample.delete;sample.manage;and');
// 路由组
Route::middleware(['auth', 'lims.permission:sample.view'])->group(function () {
Route::get('/sample', [SampleController::class, 'index']);
Route::get('/sample/{id}', [SampleController::class, 'show']);
});重要:多个权限使用**分号(;)**分隔,而非逗号。这是因为 Laravel 中间件会将逗号解析为多个参数。
4. Laravel Gate 集成(自动生效)
php
// 控制器中
public function store(Request $request)
{
$this->authorize('sample.add');
// 或
if (Gate::denies('sample.add')) {
abort(403);
}
}
// Blade 模板中(Laravel 原生)
@can('sample.add')
<button>添加样品</button>
@endcan
@cannot('sample.add')
<p>权限不足</p>
@endcannot5. 自定义 Blade 指令
blade
{{-- 单个权限 --}}
@permission('sample.add')
<button>添加样品</button>
@endpermission
{{-- 多个权限(OR) --}}
@anyPermission(['sample.add', 'sample.edit'])
<button>编辑</button>
@endanyPermission
{{-- 多个权限(AND) --}}
@allPermissions(['sample.add', 'sample.edit'])
<button>批量操作</button>
@endallPermissions
{{-- 菜单可见性 --}}
@canViewMenu(123)
<a href="/sample">样品管理</a>
@endcanViewMenu
{{-- 超级管理员 --}}
@superAdmin
<a href="/admin">管理后台</a>
@endsuperAdmin6. 配置切换 Resolver
V1:快照模式(当前)
env
# .env
RBAC_RESOLVER=App\Foundation\Rbac\Resolvers\SnapshotPermissionResolver或配置文件:
php
// config/rbac.php
'resolver' => \App\Foundation\Rbac\Resolvers\SnapshotPermissionResolver::class,V2:角色模式(切主后)
env
# .env
RBAC_RESOLVER=App\Foundation\Rbac\Resolvers\RoleBasedPermissionResolver无需修改任何业务代码! 只需切换配置即可。
7. 启用 RBAC 强制模式
env
# .env
# 开发/测试阶段(不拦截)
RBAC_ENFORCE=false
# 生产环境(强制鉴权)
RBAC_ENFORCE=true
# 缓存时间(分钟)
RBAC_CACHE_TTL_MINUTES=108. 完整示例
控制器
php
<?php
namespace App\Http\Controllers;
use App\Foundation\Rbac\Facades\LimsRbac;
use Illuminate\Http\Request;
class SampleController extends Controller
{
public function __construct()
{
// 中间件鉴权
$this->middleware('lims.permission:sample.view')->only(['index', 'show']);
$this->middleware('lims.permission:sample.add')->only(['create', 'store']);
}
public function index()
{
// Laravel Gate 鉴权
$this->authorize('sample.view');
$samples = Sample::all();
return view('sample.index', compact('samples'));
}
public function store(Request $request)
{
// Facade 鉴权
if (!LimsRbac::check('sample.add')) {
abort(403);
}
// 业务逻辑
Sample::create($request->validated());
return redirect()->route('sample.index');
}
public function batchDelete(Request $request)
{
// 批量检查权限
$permissions = LimsRbac::batchCheck(['sample.delete', 'sample.manage']);
if (!$permissions['sample.delete'] || !$permissions['sample.manage']) {
abort(403, '需要删除和管理权限');
}
// 业务逻辑
}
}Blade 视图
blade
@extends('layouts.app')
@section('content')
<div class="container">
<h1>样品管理</h1>
{{-- 添加按钮(检查权限) --}}
@permission('sample.add')
<a href="{{ route('sample.create') }}" class="btn btn-primary">
添加样品
</a>
@endpermission
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>名称</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach($samples as $sample)
<tr>
<td>{{ $sample->id }}</td>
<td>{{ $sample->name }}</td>
<td>
@anyPermission(['sample.edit', 'sample.view'])
<a href="{{ route('sample.show', $sample) }}">查看</a>
@endanyPermission
@permission('sample.delete')
<form method="POST" action="{{ route('sample.destroy', $sample) }}">
@csrf
@method('DELETE')
<button type="submit">删除</button>
</form>
@endpermission
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endsection9. 进阶:自定义 Resolver
如果需要自定义权限解析逻辑,实现 PermissionResolver 接口:
php
<?php
namespace App\CustomResolvers;
use App\Foundation\Rbac\Contracts\PermissionResolver;
class CustomPermissionResolver implements PermissionResolver
{
public function resolve(int $userId): array
{
// 自定义逻辑
return ['custom_permission' => true];
}
public function clearCache(int $userId): void
{
// 清除缓存逻辑
}
}然后在配置中指定:
php
// config/rbac.php
'resolver' => \App\CustomResolvers\CustomPermissionResolver::class,10. 性能优化
缓存预热
php
// 预热用户权限缓存
$userIds = [1, 2, 3, 4, 5];
foreach ($userIds as $userId) {
$resolver = app(\App\Foundation\Rbac\Contracts\PermissionResolver::class);
$resolver->resolve($userId); // 触发缓存
}批量清除缓存
php
use Illuminate\Support\Facades\Cache;
// 清除所有用户权限缓存
Cache::flush(); // 谨慎使用
// 或清除特定用户
$user->clearPermissionCache();
LimsRbac::clearUserCache($user);总结
Foundation/Rbac 架构的核心优势:
- 接口分离:依赖接口而非实现,易扩展
- 策略可切换:V1 快照 → V2 角色,无缝升级
- Laravel 集成:Gate + Blade 原生支持
- 便捷 API:Trait + Facade 多种用法
- 高性能:缓存 + 批量检查
切换 Resolver 无需改代码,只需改配置!