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

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头:

  1. 创建自定义认证中间件:
<?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
        );
    }
}
  1. 在Kernel.php中替换默认的auth中间件:
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    // ...其他路由中间件
];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 14:12:14