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

Laravel多Guard条件式认证:实现多角色OR逻辑认证

多Guard的OR逻辑JWT认证实现方案

这个需求完全可行,下面是几种落地的实现方案:

方案一:自定义中间件(最推荐)

直接写一个自定义中间件,接收要允许的Guard列表,循环尝试认证,只要有一个Guard验证通过就放行。

步骤:

  1. 生成中间件
php artisan make:middleware AuthenticateWithAnyGuard
  1. 编写中间件逻辑
    打开app/Http/Middleware/AuthenticateWithAnyGuard.php,替换handle方法:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Http\Request;

class AuthenticateWithAnyGuard
{
    public function handle(Request $request, Closure $next, ...$guards)
    {
        // 若未指定Guard,默认用配置的默认Guard
        $guards = empty($guards) ? [config('auth.defaults.guard')] : $guards;

        foreach ($guards as $guard) {
            try {
                // 尝试用当前Guard完成JWT认证
                auth()->guard($guard)->authenticate();
                // 认证成功后,设置当前请求的默认Guard,方便后续获取用户
                auth()->setDefaultDriver($guard);
                return $next($request);
            } catch (\Exception $e) {
                // 当前Guard认证失败,继续尝试下一个
                continue;
            }
        }

        // 所有Guard均认证失败,抛出未授权异常
        throw new AuthenticationException('Unauthorized.', $guards);
    }
}
  1. 注册中间件
    打开app/Http/Kernel.php,在$routeMiddleware数组中添加:
'auth.any' => \App\Http\Middleware\AuthenticateWithAnyGuard::class,
  1. 路由中使用
// 允许admins或vendors认证通过的路由
Route::get('/dashboard', function () {
    return response()->json([
        'user' => auth()->user(),
        'guard' => auth()->getDefaultDriver()
    ]);
})->middleware('auth.any:admins,vendors');

// 允许任意三个Guard认证通过的路由
Route::get('/public-profile', function () {
    return auth()->user();
})->middleware('auth.any:admins,vendors,customers');

方案二:闭包中间件快速实现(临时场景)

如果只是个别路由需要,不想单独写中间件,可以直接用闭包处理:

Route::get('/quick-access', function (Request $request) {
    $allowedGuards = ['admins', 'vendors'];
    $authenticated = false;

    foreach ($allowedGuards as $guard) {
        try {
            auth()->guard($guard)->authenticate();
            auth()->setDefaultDriver($guard);
            $authenticated = true;
            break;
        } catch (\Exception $e) {
            continue;
        }
    }

    if (!$authenticated) {
        return response()->json(['message' => 'Unauthorized'], 401);
    }

    return auth()->user();
});

方案三:扩展JWT-Auth原有中间件

如果你想更贴合JWT-Auth的原生逻辑,可以继承它的JwtMiddleware,修改参数解析和认证逻辑:

<?php

namespace App\Http\Middleware;

use PHPOpenSourceSaver\JWTAuth\Http\Middleware\JwtMiddleware;
use Illuminate\Auth\AuthenticationException;

class JwtAnyGuardMiddleware extends JwtMiddleware
{
    public function handle($request, \Closure $next, ...$guards)
    {
        foreach ($guards as $guard) {
            try {
                $this->authenticate($request, $guard);
                auth()->setDefaultDriver($guard);
                return $next($request);
            } catch (AuthenticationException $e) {
                continue;
            }
        }

        throw new AuthenticationException('Unauthorized.', $guards);
    }
}

注册后同样在路由中使用auth.any:guards...的方式,这种方案更贴近JWT-Auth的原生实现,但灵活性不如自定义中间件。


内容的提问来源于stack exchange,提问作者rich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:55:27