Laravel 9路由多中间件失效:仅company中间件生效问题
问题原因
你的两个中间件逻辑是互斥的:IsCompany只允许type=2的用户通过,IsConsultant只允许type=1的用户通过。而Laravel中间件是按注册顺序依次执行的,当你同时使用两个中间件时:
- 如果当前用户是
type=1,第一个执行的company中间件会判断不通过,直接返回重定向,后续的consultant中间件根本不会运行; - 如果当前用户是
type=2,company中间件通过后,consultant中间件会判断不通过,同样返回重定向。
这就导致看起来只有第一个中间件生效。
解决方案
你的需求应该是允许type=1(顾问)或type=2(企业)的用户访问路由,所以需要将两个判断合并为逻辑或的关系,推荐以下两种方式:
方式一:创建组合中间件(推荐)
新建一个中间件IsCompanyOrConsultant,整合两种用户类型的判断:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class IsCompanyOrConsultant { public function handle(Request $request, Closure $next) { $user = Auth::user(); // 允许type为1(顾问)或2(企业)的用户通过 if ($user && in_array($user->type, [1, 2])) { return $next($request); } return redirect('dashboard')->with('error','You have no access'); } }
在app/Http/Kernel.php的routeMiddleware中注册这个新中间件:
protected $routeMiddleware = [ // 其他中间件... 'company-or-consultant' => \App\Http\Middleware\IsCompanyOrConsultant::class, ];
然后路由使用这个组合中间件:
Route::middleware(['company-or-consultant'])->group(function () { Route::resource('/tasks', TaskController::class); });
方式二:修改现有中间件逻辑(不推荐,易混淆)
如果一定要保留原有两个中间件,可以修改它们的逻辑,当不满足自身类型时,不直接重定向,而是继续执行下一个中间件,但这种方式会让中间件的职责变得模糊:
// 修改IsCompany中间件 class IsCompany { public function handle(Request $request, Closure $next) { $user = Auth::user(); // 如果是企业用户,直接通过;否则继续执行下一个中间件 if ($user && $user->type == 2) { return $next($request); } // 不直接重定向,交给下一个中间件判断 return $next($request); } } // 修改IsConsultant中间件 class IsConsultant { public function handle(Request $request, Closure $next) { $user = Auth::user(); if ($user && $user->type == 1) { return $next($request); } // 两个中间件都不满足时,才重定向 return redirect('dashboard')->with('error','You have no access'); } }
然后路由保持原来的写法,但注意顺序:必须把最后判断重定向的中间件放在数组最后:
Route::middleware(['company', 'consultant'])->group(function () { Route::resource('/tasks', TaskController::class); });
总结
推荐使用第一种方式,因为它更符合单一职责原则,逻辑清晰,也便于后续维护。
内容的提问来源于stack exchange,提问作者alex
相关产品推荐
相关产品推荐

