You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:50:21