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

使用Laravel Sanctum跨子域遇419 CSRF令牌不匹配问题求助

解决Laravel Sanctum跨子域认证的419 CSRF令牌不匹配问题

我之前也碰到过几乎一模一样的跨子域Sanctum认证坑,折腾了好几个小时才搞定,给你分享几个亲测有效的排查和解决方向:

1. 检查Cookie的SameSite与Secure配置

Laravel默认的Session Cookie SameSite属性是lax,这在跨子域场景下可能会被浏览器拦截。你需要修改config/session.php:

'same_site' => 'none',
'secure' => env('SESSION_SECURE_COOKIE', true),

同时在.env里确保SESSION_SECURE_COOKIE=true(因为SameSite=None必须配合HTTPS使用,生产环境一定要开启,本地开发如果用HTTP的话可以暂时设为false,但上线前记得改回来)。

2. 修正SANCTUM_STATEFUL_DOMAINS配置

这个配置很容易踩格式坑:

  • 去掉.env里的引号,比如改成SANCTUM_STATEFUL_DOMAINS=domain.com(有些环境下引号会导致解析错误)
  • 如果你的应用有www前缀(比如www.domain.com),要把它也加进去:SANCTUM_STATEFUL_DOMAINS=domain.com,www.domain.com
  • 本地开发如果用了端口(比如domain.com:3000),必须带上端口号

3. 确保NextJS请求正确携带凭证和令牌

用axios或者fetch的时候,一定要开启携带凭证的配置,并且正确提取XSRF令牌:

用axios的示例:

import axios from 'axios';

// 先获取CSRF Cookie
await axios.get('https://api.domain.com/sanctum/csrf-cookie', {
  withCredentials: true
});

// 提取XSRF令牌
const getCsrfToken = () => {
  const cookie = document.cookie.split('; ').find(row => row.startsWith('XSRF-TOKEN='));
  return cookie ? decodeURIComponent(cookie.split('=')[1]) : '';
};

// 登录请求
await axios.post('https://api.domain.com/login', {
  email: 'your-email',
  password: 'your-password'
}, {
  withCredentials: true,
  headers: {
    'X-XSRF-TOKEN': getCsrfToken()
  }
});

如果用fetch的话,要设置credentials: 'include'。

4. 检查Laravel CORS配置

打开config/cors.php,确保这几个关键项正确:

'allowed_origins' => ['https://domain.com'], // 或者具体的前端域名,不要用*如果需要带凭证
'allowed_methods' => ['*'],
'allowed_headers' => ['*'],
'supports_credentials' => true, // 这个必须设为true,否则跨域Cookie会被拦截

5. 清除浏览器缓存或强制刷新CSRF令牌

有时候浏览器会缓存旧的CSRF Cookie,导致令牌不匹配。可以:

  • 手动清除浏览器的Cookie和缓存
  • 或者在Laravel的/sanctum/csrf-cookie路由里添加缓存控制头,避免缓存:
Route::get('/sanctum/csrf-cookie', function () {
    return response()->json(['status' => 'ok'])
        ->withHeaders([
            'Cache-Control' => 'no-store, no-cache, must-revalidate',
            'Pragma' => 'no-cache',
        ]);
});

6. 再次确认SESSION_DOMAIN的正确性

确保.env里的SESSION_DOMAIN=.domain.com,前面的点不能少,这样所有子域(包括api.domain.com和domain.com)才能共享这个Session Cookie。如果写成api.domain.com,主域的前端就无法访问这个Cookie了。

我当时主要是SameSite设置为none和CORS的supports_credentials没开启导致的问题,你可以逐个排查这些点,应该能解决419错误。

内容的提问来源于stack exchange,提问作者Carwyn Stephen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:43:36