Laravel多用户级别路由权限异常:仅最后分组用户可登录求助
问题描述
业务需求中创建了admin、user、viewer三个用户级别,在web.php中通过以下路由分组配置不同级别用户对/dashboard的访问权限:
Route::group(["middleware" => ["auth","checklevel:admin"]], function(){ Route::get("/dashboard", "DashboardController@index")->name("dashboard"); }); Route::group(["middleware" => ["auth","checklevel:user"]], function(){ Route::get("/dashboard", "DashboardController@index")->name("dashboard"); }); Route::group(["middleware" => ["auth","checklevel:viewer"]], function(){ Route::get("/dashboard", "DashboardController@index")->name("dashboard"); });
出现异常情况:
- 按上述分组顺序,仅viewer级别用户可访问
/dashboard; - 若将admin分组移至底部,则仅admin级别可访问;
- 即便将user分组移至底部,user级别仍无法登录。
自定义CheckLevel中间件代码如下:
<?php namespace App\Http\Middleware; use Closure; class CheckLevel { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next, ...$levels) { if (in_array($request->user()->level,$levels)){ return $next($request); } return redirect("/"); } }
问题原因分析
- 路由覆盖问题:Laravel中相同HTTP方法(GET)和路径(/dashboard)的路由,后面定义的会直接覆盖前面的。因此实际生效的只有最后一个路由分组,只有该分组对应的用户级别能通过中间件校验,其他级别用户访问时会触发中间件的重定向逻辑。
- user级别无法访问的额外可能:需确认数据库中user用户的
level字段值是否与中间件传递的user参数完全一致(包括大小写,比如是否误写为User或USER)。
解决方案
方案一:合并路由(推荐)
将三个路由分组合并为一个,通过中间件传递多个级别参数,这样所有指定级别用户都能访问同一个/dashboard路由:
Route::group(["middleware" => ["auth","checklevel:admin,user,viewer"]], function(){ Route::get("/dashboard", "DashboardController@index")->name("dashboard"); });
该方案下,CheckLevel中间件的$levels参数会接收["admin","user","viewer"]数组,只要用户的level值在数组内即可通过校验。
方案二:区分路由(若不同级别需不同逻辑)
如果不同级别用户需要访问不同的Dashboard页面,可修改路由路径或名称,避免路由覆盖:
// admin专属路由 Route::group(["middleware" => ["auth","checklevel:admin"]], function(){ Route::get("/dashboard/admin", "DashboardController@adminIndex")->name("dashboard.admin"); }); // user专属路由 Route::group(["middleware" => ["auth","checklevel:user"]], function(){ Route::get("/dashboard/user", "DashboardController@userIndex")->name("dashboard.user"); }); // viewer专属路由 Route::group(["middleware" => ["auth","checklevel:viewer"]], function(){ Route::get("/dashboard/viewer", "DashboardController@viewerIndex")->name("dashboard.viewer"); });
额外检查(针对user级别无法访问)
查看数据库中user用户的level字段值,确保其与中间件传递的user字符串完全匹配,无大小写或拼写错误。
内容的提问来源于stack exchange,提问作者ITG
相关产品推荐
相关产品推荐

