Laravel中如何在路由前缀中分配用户角色?
问题描述
用户已完成以下配置:
web.php 代码
Route::group(['prefix' => {User Role}, 'middleware' => 'AuthUser:superadmin,admindesa'], function() { Route::get('/', 'DashboardC@index'); Route::get('/penduduk', 'PendudukC@index'); Route::get('/penduduk/{id}/detail', 'PendudukC@detail'); }); Route::group(['prefix' => 'superadmin', 'middleware' => 'AuthUser:superadmin'], function() { Route::get('/pengguna', 'PenggunaC@index'); Route::get('/pengguna/{id}/edit', 'PenggunaC@edit'); Route::post('/pengguna/{id}/prosesedit', 'PenggunaC@prosesEdit'); Route::get('/pengguna/{id}/hapus', 'PenggunaC@hapus'); Route::post('/ajax/pengguna', 'AjaxC@pengguna'); });
AuthUser.php 代码
class AuthUser { public function handle($request, Closure $next, ...$roles) { $auth = auth('web')->user(); if (!$auth || !in_array($auth->role, $roles)){ \Session::flash('flash_message', array('pesan' => 'Silahkan login untuk melanjutkan', 'tipe' => 'warning')); return redirect()->route('login'); } return $next($request); } }
需要确定路由前缀的{User Role}位置填写什么内容,以实现用户角色分配。
解决方案
你有两种可行的实现方式,可根据实际需求选择:
方式1:拆分路由组(简单直观)
直接复制共享路由组,分别为superadmin和admindesa设置专属前缀,无需处理动态参数的复杂验证:
// 超级管理员共享路由 Route::group(['prefix' => 'superadmin', 'middleware' => 'AuthUser:superadmin'], function() { Route::get('/', 'DashboardC@index'); Route::get('/penduduk', 'PendudukC@index'); Route::get('/penduduk/{id}/detail', 'PendudukC@detail'); }); // 村管理员共享路由 Route::group(['prefix' => 'admindesa', 'middleware' => 'AuthUser:admindesa'], function() { Route::get('/', 'DashboardC@index'); Route::get('/penduduk', 'PendudukC@index'); Route::get('/penduduk/{id}/detail', 'PendudukC@detail'); }); // 超级管理员专属路由(保留原代码) Route::group(['prefix' => 'superadmin', 'middleware' => 'AuthUser:superadmin'], function() { Route::get('/pengguna', 'PenggunaC@index'); Route::get('/pengguna/{id}/edit', 'PenggunaC@edit'); Route::post('/pengguna/{id}/prosesedit', 'PenggunaC@prosesEdit'); Route::get('/pengguna/{id}/hapus', 'PenggunaC@hapus'); Route::post('/ajax/pengguna', 'AjaxC@pengguna'); });
这种方式优势是代码清晰、维护简单,适合角色数量较少的场景。
方式2:动态路由参数+约束(避免重复代码)
将{User Role}替换为动态路由参数{role},添加路由约束限制允许的角色值,并修改中间件验证当前用户角色与路由前缀角色一致:
修改后的 web.php
// 共享路由组:使用动态参数并添加角色约束 Route::group(['prefix' => '{role}', 'middleware' => 'AuthUser:superadmin,admindesa'], function() { Route::get('/', 'DashboardC@index'); Route::get('/penduduk', 'PendudukC@index'); Route::get('/penduduk/{id}/detail', 'PendudukC@detail'); })->where('role', 'superadmin|admindesa'); // 约束路由参数只能是指定角色 // 超级管理员专属路由(保留原代码) Route::group(['prefix' => 'superadmin', 'middleware' => 'AuthUser:superadmin'], function() { Route::get('/pengguna', 'PenggunaC@index'); Route::get('/pengguna/{id}/edit', 'PenggunaC@edit'); Route::post('/pengguna/{id}/prosesedit', 'PenggunaC@prosesEdit'); Route::get('/pengguna/{id}/hapus', 'PenggunaC@hapus'); Route::post('/ajax/pengguna', 'AjaxC@pengguna'); });
修改后的 AuthUser.php
class AuthUser { public function handle($request, Closure $next, ...$roles) { $auth = auth('web')->user(); if (!$auth || !in_array($auth->role, $roles)){ \Session::flash('flash_message', array('pesan' => 'Silahkan login untuk melanjutkan', 'tipe' => 'warning')); return redirect()->route('login'); } // 验证路由前缀的角色与当前用户角色匹配,防止越权访问 $routeRole = $request->route()->parameter('role'); if ($routeRole && $routeRole !== $auth->role) { abort(403, 'Akses ditolak'); } return $next($request); } }
这种方式适合角色较多的场景,能减少代码重复,同时通过约束和验证确保访问安全。
内容的提问来源于stack exchange,提问作者Aditya Pratama
相关产品推荐
相关产品推荐

