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

Vue3+Quasar SPA对接Laravel API遇CSRF令牌不匹配(419错误)

问题:Laravel Sanctum + Axios 自动携带XSRF-TOKEN失败导致419错误

环境与问题

  • Vue3 + Quasar SPA部署在localhost:8080,Laravel API部署在localhost:80(Docker容器运行)
  • 页面刷新时已调用/sanctum/csrf-cookie,浏览器Cookie中已存在XSRF-TOKEN
  • 调用/login接口时返回419状态码,手动添加X-XSRF-TOKEN请求头后请求成功,但Axios未自动完成该过程

现有配置

Quasar/Vue Axios全局配置

axios.defaults.withCredentials = true;
axios.defaults.baseURL = 'http://localhost/'
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'

Laravel .env配置

...
APP_URL=http://localhost
...
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost
SANCTUM_STATEFUL_DOMAINS=localhost:8080

Laravel cors.php配置

'paths' => ['api/*', 'sanctum/csrf-cookie', 'login'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,

Laravel Kernel.php配置

'api' => [
    EnsureFrontendRequestsAreStateful::class,
    ThrottleRequests::class . ':api',
    SubstituteBindings::class,
],

/login请求的Cookie头信息

Cookie:
XSRF-TOKEN=eyJpdiI6InJ0SXhRZDVEL21JaEUvL0ptTGdmUlE9PSIsInZhbHVlIjoiU28zenNEQ1VOYTR3NXRVd1JtcU1RaUsvK1BCTHpNUGtUZ3c3T3I0d3lKQjhlZzNjMkVIeDBoOFZWanJDVkw2cWc0RGRDM0NWako0cnN1RXdveThwZkE4dW51aS9Ia1FYVXVsSlpqdW9CK1F3amJTMlFITzhpSCtudDYvY2VpUnUiLCJtYWMiOiIyODkyMzhjYjU5YzMzODY2YTkxZTY3M2MzOWZkNDkwMGQyYjBjNDg0ZTgwMzM3ZDc5NjYwYTcyNWFmZTUyZjExIiwidGFnIjoiIn0%3D; laravel_session=eyJpdiI6IlQxYXZ4WGhYZGZ5Lzk2WlF5QzJRUHc9PSIsInZhbHVlIjoidE5QQUpaeFh3WWg4cjFJNG82SXNDY1FGUmplWFN5cG5na08zazRmbXFJRFhJVWdUZS81UzJ1RWNaaC84VWxxcTFPdWNuTXd5K0pDaW0zTDliME5BSHl2ZGw4M01lbk1EUDl6SnlVWWFLM2lxNHBTOFBmei9QQXhMaTZLazJSeEEiLCJtYWMiOiIwNjFlNTFkNzIzZTIyZDhjYTg0MmVhMGViMGZjYTU4MmZjY2VmOGMyOWRjODgyNGY3NmE3NjExZDIyYWVhMDU1IiwidGFnIjoiIn0%3D; 3mcV2b1Mp2zT3MoKAWWTOeGlp0TkNFu9FneRzMLK=eyJpdiI6InY1cUYwaXhjdnZlQVRiNDNqaFRMMEE9PSIsInZhbHVlIjoiaE52dVg0dnRYdmE2dDVUT0lUUkJWeXAyaXNkaXMvZkw3RjJwT0hrbkdybUx4K0JyZ2RZV2lMYjEvT3F2TUEvOWQzejkxN05SaHlZMVliUktmUnhVRkwwYTB4cDYzUVB5VFA3MnA5SmlhMmc1Y0VSY3NyMm1JVnd2Vk1XZmFlWU05dEZJWVQrSjFqQ2h6aktFemdFVWZ6cjJBM2MydHNIMlcxRSsvWk1xaDU0Y1RDcHBFUndOL2ZlMXBVWVhyUEQrNS8vOTI5Qmx0TmpMQUtZQ0sxUHZLMEd5MnpGdC91SnVDeDJ5RkF4Tkc0dUphNHhLRFQwUE5Vc0hlR29JaVZqQ3p4Yi9wTFpMUE42UmJOWXoxN0V2bGZlZHduTVRmZUdkcHVnLzBkOWQ0emQyajhjelptSG9XUzRDb3lmZVlpMk5OK1p0R2R2eTdET2FjcTVhVGR4WmRtNVd4ekQ4SHZaeEg3cTUxY0Y2ZVhFdWhJeDh1SUkreUkwdFBmMjErUmdGIiwibWFjIjoiYWVmY2NkY2NiZmJiY2ZhNjkyMTVhODE2MTg0MjkxNTYxZWQ0N2I4NzMyY2RjOWE2NDdiNGY4NjljYjk5NDY0YyIsInRhZyI6IiJ9

补充发现

Axios自动携带了包含XSRF-TOKEN的Cookie头,但未自动生成X-XSRF-TOKEN请求头。手动添加该头后请求成功,手动实现代码如下:

const login = async () => {
  let cookies;
  await axios.get("/sanctum/csrf-cookie").then((response) => {
    const { get } = useCookies(['XSRF-TOKEN']);
    cookies = get('XSRF-TOKEN');
  });

  axios.defaults.headers['X-XSRF-TOKEN'] = cookies;
  await axios.post("/login", form).then((response) => {
    console.log(response)
  });
}

解决方案

要实现Axios自动处理X-XSRF-TOKEN头,需完成以下配置:

  1. 显式配置Axios的XSRF参数
    Axios默认会读取XSRF-TOKENCookie并生成X-XSRF-TOKEN请求头,但显式配置可避免隐式匹配问题,将以下代码加入Axios全局配置:
axios.defaults.xsrfCookieName = 'XSRF-TOKEN'; // 与Laravel设置的Cookie名一致
axios.defaults.xsrfHeaderName = 'X-XSRF-TOKEN'; // 与Laravel期望的请求头名一致
  1. 简化登录请求逻辑
    调用/sanctum/csrf-cookie后,直接发送登录请求即可,Axios会自动携带所需头:
const login = async () => {
  await axios.get('/sanctum/csrf-cookie');
  const response = await axios.post('/login', form);
  console.log(response);
}
  1. Docker环境校验
    确保Docker容器端口映射正确(宿主机80端口映射到容器80),容器内APP_URL和SESSION_DOMAIN配置与宿主机一致,避免Cookie作用域不匹配。

验证方法

发送请求前打开浏览器开发者工具Network面板,查看/login请求的Request Headers中是否包含X-XSRF-TOKEN头,且值与Cookie中的XSRF-TOKEN一致(Axios会自动解码Cookie中的URL编码值)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 12:49:55