Laravel 9中Auth:sanctum中间件无法保护路由的问题排查
Laravel Sanctum auth:sanctum中间件异常排查
我维护的Laravel 9站点历经多版本迭代,刚安装Sanctum实现API令牌生成功能,令牌生成正常,但用auth:sanctum保护路由时出现异常:
- Postman访问
/api/tokens/validate,无论是否传令牌都能返回有效响应,中间件未生效 - 浏览器访问同一路由会被重定向到登录页
已核对kernel.php的api中间件组配置,尝试移除EnsureFrontendRequestsAreStateful后问题依旧,以下是相关配置代码:
相关配置代码
api.php
Route::middleware('auth:sanctum')->get('tokens/validate', function () { return ['data' => 'token is valid']; });
kernel.php 中间件组配置
protected $middlewareGroups = [ 'web' => [ EncryptCookies::class, AddQueuedCookiesToResponse::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, ], 'api' => [ EnsureFrontendRequestsAreStateful::class, 'throttle:60,1', SubstituteBindings::class, ], ];
sanctum.php 配置
<?php use Laravel\Sanctum\Sanctum; return [ 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,arcane.city,dev.arcane.city', Sanctum::currentApplicationUrlWithPort() ))), 'guard' => ['web'], 'expiration' => null, 'middleware' => [ 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, ], ];
auth.php 配置
<?php return [ 'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], ], 'passwords' => [ 'users' => [ 'provider' => 'users', 'email' => 'auth.emails.password', 'table' => 'password_resets', 'expire' => 60, ], ], 'driver' => 'eloquent', 'model' => 'App\Models\User', 'table' => 'users', 'failed' => 'Unable to log in' ];
问题原因及修复方案
1. Sanctum 默认Guard配置错误
当前sanctum.php中guard设置为['web'],会让Sanctum优先使用session认证而非令牌认证。对于API路由,需修改为使用api guard:
'guard' => ['api'],
2. API路由未应用API中间件组
当前路由仅添加auth:sanctum中间件,未加入api中间件组,导致无状态认证逻辑未启用。修改api.php:
// 方式一:直接添加api中间件 Route::middleware(['api', 'auth:sanctum'])->get('tokens/validate', function () { return ['data' => 'token is valid']; }); // 方式二:批量包裹API路由 Route::middleware('api')->group(function () { Route::middleware('auth:sanctum')->get('tokens/validate', function () { return ['data' => 'token is valid']; }); });
3. Auth配置中API Guard驱动错误
当前auth.php中api guard的driver为旧版token,Sanctum需要使用sanctum驱动:
'api' => [ 'driver' => 'sanctum', 'provider' => 'users', ],
4. 浏览器重定向问题
浏览器访问时重定向到登录页,是因为sanctum.php的stateful包含当前域名,EnsureFrontendRequestsAreStateful会将这类请求视为有状态请求,优先走session认证。解决方式:
- 从
SANCTUM_STATEFUL_DOMAINS中移除当前站点域名,强制API使用无状态令牌认证 - 若需保留stateful配置,确保浏览器请求携带
Authorization: Bearer {token}头,且添加Accept: application/json请求头(避免Laravel返回重定向响应)
内容的提问来源于stack exchange,提问作者Geoff Maddock
相关产品推荐
相关产品推荐

