Laravel 8路由如何设置OR逻辑中间件 实现两种认证方式二选一访问
问题原因
你将两个认证中间件同时配置到middleware数组中时,Laravel默认要求所有中间件全部校验通过才会放行,属于「且」的逻辑,不符合你要的「任意一种认证通过即可」的「或」需求。你尝试的|拼接写法不符合Laravel中间件的参数传递规则,因此无法生效。
解决方案
方案1:使用auth中间件多guard配置(适用于认证方式均为auth guard的场景)
如果你的基础认证已经配置为auth的独立guard,可以直接给auth中间件传入多个guard,用逗号分隔,原生支持任意一个guard认证通过即放行:
Route::group(['middleware' => ['auth:sanctum,basic']], function () { Route::get('/images', [ImageController::class, 'index']); });
注意:该方案不适用于auth.basic.once这类独立的非auth中间件。
方案2:自定义组合认证中间件(通用方案,支持任意中间件组合)
这种方案兼容性最高,适合任意两种中间件的「或」逻辑校验:
- 执行Artisan命令创建自定义中间件:
php artisan make:middleware EitherAuth
- 编辑生成的
app/Http/Middleware/EitherAuth.php文件,写入逻辑:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Auth\AuthenticationException; use Illuminate\Http\Request; class EitherAuth { public function handle(Request $request, Closure $next) { // 尝试第一种认证:sanctum try { app('auth')->guard('sanctum')->authenticate(); return $next($request); } catch (AuthenticationException $e) {} // 尝试第二种认证:basic.once try { return app('router')->prepareResponse($request, app(\Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class)->handle($request, function ($req) use ($next) { return $next($req); }, 'basic', 'once') ); } catch (AuthenticationException $e) {} // 两种都失败抛出认证异常 throw new AuthenticationException(); } }
- 注册中间件到
app/Http/Kernel.php的$routeMiddleware数组中:
protected $routeMiddleware = [ // 其他原有中间件 'either.auth' => \App\Http\Middleware\EitherAuth::class, ];
- 路由中直接使用自定义的中间件即可:
Route::group(['middleware' => ['either.auth']], function () { Route::get('/images', [ImageController::class, 'index']); });
内容的提问来源于stack exchange,提问作者Công Nguyễn
相关产品推荐
相关产品推荐

