Laravel Jetstream Vue中如何传递Spatie用户角色至所有路由?
在Jetstream Vue项目中传递Spatie用户角色实现权限视图控制
方案一:通过Inertia全局共享用户角色数据
Jetstream基于Inertia构建,Inertia支持将全局数据共享到所有前端Vue组件,这是最贴合Jetstream生态的实现方式:
- 修改Laravel端的
HandleInertiaRequests中间件
找到app/Http/Middleware/HandleInertiaRequests.php,在share方法中扩展用户的auth数据,加入Spatie管理的角色信息:
public function share(Request $request) { return array_merge(parent::share($request), [ 'auth' => [ 'user' => fn () => $request->user() ? [ 'id' => $request->user()->id, 'name' => $request->user()->name, 'email' => $request->user()->email, // 单角色场景:取第一个角色名称 'role' => $request->user()->roles->pluck('name')->first(), // 多角色场景:返回所有角色名称数组 // 'roles' => $request->user()->roles->pluck('name'), // 可选:同时共享权限列表 // 'permissions' => $request->user()->getPermissionNames(), ] : null, ], ]); }
- 前端Vue组件中使用角色数据
所有Vue组件都可以通过$page.props.auth.user.role直接获取角色,你的导航代码可以修改为:
<!-- Navigation Links --> <div v-if="$page.props.auth.user.role === 'admin'" class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex max-w-xl md:max-w-7xl flex-wrap justify-around"> <NavLink :href="route('dashboard')" :active="route().current('dashboard')"> Dashboard </NavLink> </div>
方案二:自定义中间件共享角色数据
如果需要更灵活的控制(比如仅在特定路由组共享),可以自定义中间件实现:
- 创建自定义中间件
执行Artisan命令生成中间件:
php artisan make:middleware ShareUserRole
- 编写中间件逻辑
打开app/Http/Middleware/ShareUserRole.php,添加角色共享代码:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Inertia\Inertia; class ShareUserRole { public function handle(Request $request, Closure $next) { if ($request->user()) { Inertia::share([ 'auth.user.role' => $request->user()->roles->pluck('name')->first(), // 可选:共享权限 // 'auth.user.permissions' => $request->user()->getPermissionNames(), ]); } return $next($request); } }
- 注册中间件
打开app/Http/Kernel.php,将中间件添加到web中间件组(全局生效)或路由组中:
protected $middlewareGroups = [ 'web' => [ // ...其他中间件 \App\Http\Middleware\ShareUserRole::class, ], ];
额外:路由层面的角色验证
结合Spatie的权限中间件,可以在后端直接控制路由访问权限,避免前端视图控制的局限性:
// 仅允许admin角色访问的路由组 Route::middleware(['auth', 'role:admin'])->group(function () { Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard'); // 其他admin专属路由 });
内容的提问来源于stack exchange,提问作者Mohammad Hossein
相关产品推荐
相关产品推荐

