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

子域名下Laravel Sanctum+ReactJS SPA跨域CORS错误求助

Laravel Sanctum跨域登录CORS错误排查与解决

问题背景

已花费5天时间尝试解决跨域问题,API部署在api.mydomain.edu.af,SPA部署在spa.mydomain.edu.af。能正常通过sanctum/csrf-cookie接口获取XSRF-Token,但调用登录接口api.mydomain.edu.af/api/login(定义在api.php)时触发CORS错误。

相关配置及请求详情

1. .env配置

SANCTUM_STATEFUL_DOMAINS=mydomain.edu.af
SESSION_DOMAIN=.mydomain.edu.af

2. Kernel.php中间件组配置

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

3. cors.php配置

'paths' => ['api/*', 'sanctum/csrf-cookie'],

'allowed_methods' => ['*'],

'allowed_origins' => ['*'],

'allowed_origins_patterns' => [],

'allowed_headers' => ['*'],

'exposed_headers' => [],

'max_age' => 0,

'supports_credentials' => true,

4. sanctum.php配置

'stateful' => explode(',', env(
    'SANCTUM_STATEFUL_DOMAINS',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1,'.parse_url(env('APP_URL'), PHP_URL_HOST)
)),

5. ReactJS Axios登录请求(已成功获取csrf-cookie)

axios.defaults.withCredentials = true;
await axios
  .post(global.config.main.Api_Url + "/api/login", postData, {
    headers: { Accept: "application/json" },
  })
  .then((response) => {
    if (response.status === 200) {
      signIn({
        token: response.data["token"],
        expiresIn: 3600,
        tokenType: "Bearer",
        authState: { firstname: response.data["firstname"] },
      });
    } else {
      setError("Something Went Wrong!");
    }
  });

解决方案

1. 修正SANCTUM_STATEFUL_DOMAINS配置

将.env中的SANCTUM_STATEFUL_DOMAINS改为包含SPA域名:

SANCTUM_STATEFUL_DOMAINS=spa.mydomain.edu.af,api.mydomain.edu.af

Sanctum需要明确指定所有允许的有状态前端域名,仅填根域名可能无法识别子域名的SPA请求。

2. 检查APP_URL配置

确保.env中的APP_URL指向API域名:

APP_URL=https://api.mydomain.edu.af

sanctum.php中会自动读取该值加入状态域名列表,避免遗漏。

3. 确认CORS中间件优先级

确保HandleCors中间件在Kernel.php的$middleware数组最顶部加载,优先级高于其他中间件:

protected $middleware = [
    \Illuminate\Http\Middleware\HandleCors::class, // 放在最前面
    \App\Http\Middleware\TrustProxies::class,
    // ...其他中间件
];

如果CORS中间件加载过晚,可能在其他中间件处理请求前未正确设置跨域头。

4. 验证XSRF-Token是否正确携带

在Axios请求中手动添加X-XSRF-TOKEN头,确保Cookie中的XSRF-Token被正确传递:

await axios
  .post(global.config.main.Api_Url + "/api/login", postData, {
    headers: {
      Accept: "application/json",
      'X-XSRF-TOKEN': decodeURIComponent(document.cookie.match(/XSRF-TOKEN=([^;]+)/)[1])
    },
  })

部分环境下Axios可能无法自动读取并携带该头,手动添加可避免验证失败触发的CORS类错误。

5. 清除缓存并重启服务

修改配置后执行以下命令清除缓存:

php artisan config:clear
php artisan cache:clear

重启PHP-FPM和Web服务器(如Nginx/Apache),确保新配置生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 07:05:38