Laravel中如何为动态路由配置Spatie Permission权限中间件?
解决Laravel动态路由搭配Spatie Permission的权限校验问题
针对你用单动态路由对应多个页面、需要按页面匹配不同权限的场景,这里提供两种实用方案:
方案一:自定义专属页面权限中间件
这种方式把权限校验逻辑抽离到中间件,路由配置更简洁,也方便后续扩展。
- 创建自定义中间件
执行Artisan命令生成中间件:
php artisan make:middleware PagePermission
- 编写中间件逻辑
打开生成的app/Http/Middleware/PagePermission.php,修改handle方法:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Str; use Symfony\Component\HttpFoundation\Response; class PagePermission { public function handle(Request $request, Closure $next): Response { $page = $request->route('page'); // 按规则生成对应权限名 // 若你的权限是下划线命名(如terms_and_condition.view),替换为str_replace('-', '_', $page) $permission = Str::camel($page) . '.view'; // 无权限则返回403 abort_unless($request->user()->can($permission), 403, '你没有访问该页面的权限'); return $next($request); } }
- 注册中间件
打开app/Http/Kernel.php,在$routeMiddleware数组中添加中间件别名:
protected $routeMiddleware = [ // ...其他已有的中间件 'page.permission' => \App\Http\Middleware\PagePermission::class, ];
- 路由中使用中间件
把自定义中间件绑定到动态路由上,同时保留页面白名单限制:
Route::get('/{page}', [PageController::class, 'index']) ->where('page', 'about|service|terms-and-condition|privacy-policy|contact') ->middleware(['auth', 'page.permission']);
方案二:直接在控制器方法中校验权限
如果场景简单不想新增中间件,可以直接在PageController的index方法里做校验:
<?php namespace App\Http\Controllers; use Illuminate\Support\Str; class PageController extends Controller { public function index(string $page) { // 生成对应权限名,规则和中间件一致 $permission = Str::camel($page) . '.view'; // 校验:页面不在白名单返回404,无权限返回403 abort_unless(in_array($page, ['about', 'service', 'terms-and-condition', 'privacy-policy', 'contact']), 404); abort_unless(auth()->user()->can($permission), 403, '你没有访问该页面的权限'); return view("pages.$page"); } }
此时路由只需保留基础配置:
Route::get('/{page}', [PageController::class, 'index']) ->where('page', 'about|service|terms-and-condition|privacy-policy|contact') ->middleware('auth');
注意事项
- 确保权限名称和生成规则完全匹配,比如权限是
terms_and_condition.view,就把Str::camel($page)替换为str_replace('-', '_', $page)。 - 路由的
where限制必须保留,防止恶意构造的page参数触发不必要的权限校验或视图查找错误。
内容的提问来源于stack exchange,提问作者Chandan A.
相关产品推荐
相关产品推荐

