Laravel Sanctum未认证请求CORS错误:缺少Access-Control-Allow-Origin头
问题原因及解决方案
核心原因
问题出在Laravel中间件的执行顺序:
- 当请求未携带有效token时,
auth:sanctum中间件会直接提前返回401未认证响应。 - 如果负责添加CORS头的
HandleCors中间件排在auth:sanctum之后,它就没机会给这个401响应注入CORS相关字段,导致前端触发跨域错误。 - 而带有效token请求时,
auth:sanctum验证通过,请求会流转到后续中间件(包括HandleCors),因此响应头能正常带上CORS字段;移除auth:sanctum时,请求直接通过,CORS中间件也能正常工作。
解决方案
1. 调整中间件执行顺序(最优方案)
打开app/Http/Kernel.php,将\Illuminate\Http\Middleware\HandleCors::class移到全局$middleware数组的最前面,确保它在所有认证类中间件之前执行:
protected $middleware = [ // 优先执行CORS中间件,确保所有响应都带上CORS头 \Illuminate\Http\Middleware\HandleCors::class, \App\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\CheckForMaintenanceMode::class, // ...其他全局中间件 ];
这样即使auth:sanctum提前返回401响应,CORS头也已经被添加完成。
2. 验证cors.php配置的完整性
确认config/cors.php的配置覆盖你的业务场景:
paths需包含你的API路径,比如:'paths' => ['api/*', 'sanctum/csrf-cookie'],allowed_origins或allowed_origins_patterns要包含前端域名(比如Angular默认的http://localhost:4200):'allowed_origins' => ['http://localhost:4200'],- 保持
supports_credentials => true,同时确保Angular请求时配置了withCredentials: true(在HttpClient请求中设置)。
3. 自定义未认证响应(备选方案)
如果不想调整中间件顺序,可以自定义auth:sanctum的未认证响应,手动注入CORS头:
- 创建自定义认证中间件:
<?php namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; class Authenticate extends Middleware { protected function redirectTo($request) { if (!$request->expectsJson()) { return route('login'); } } protected function unauthenticated($request, array $guards) { $response = response()->json(['message' => 'Unauthenticated.'], 401); // 手动添加CORS头 $corsConfig = config('cors'); $response->headers->set('Access-Control-Allow-Origin', $corsConfig['allowed_origins'][0]); $response->headers->set('Access-Control-Allow-Credentials', 'true'); throw new \Illuminate\Auth\AuthenticationException( 'Unauthenticated.', $guards, $response ); } }
- 在
Kernel.php中替换默认的auth中间件:
protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, // ...其他路由中间件 ];
内容的提问来源于stack exchange,提问作者Judy Dick
相关产品推荐
相关产品推荐

