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

Laravel Sanctum+Fortify Vue SPA登出419/接口401问题求助

问题:Laravel Sanctum + Fortify 实现Vue SPA认证异常

登录功能正常:调用POST /sanctum/csrf-cookie可在客户端设置Cookie,携带该Cookie的X-XSRF-TOKEN头和withCredentials参数调用POST /login能完成认证。但出现两个异常:

  • 调用POST /logout时,即使携带CSRF令牌,仍返回419 unknown status csrf-token mismatch错误
  • 调用GET api/users/auth返回401 unauthorized(响应内容为unauthenticated)

已完成相关配置:cors.php路径设置、.env变量配置,以及针对SPA认证的fortify.php和fortifyServiceProvider.php配置。

登录代码

function getCookie(name) {
  const value = document.cookie
  const parts = value.split(name)
  if (parts.length === 2) {
    return parts.pop().split(';').shift()
  }
}

const login = async () => {
  error.value = null
  const payload = {
    email: email.value,
    password: password.value
  }

  axios.get('http://localhost:80/sanctum/csrf-cookie').then(() => {
    const csrfToken = getCookie('XSRF-TOKEN')

    axios
      .post('http://localhost:80/login', payload, {
        headers: {
          'X-XSRF-TOKEN': decodeURIComponent(csrfToken)
        },
        withCredentials: true
      })
      .then((response) => {
        if (response.data.error) {
          error.value = response.data.error
        } else {
          router.push('/')
        }
      })
  })
}

登出代码

const logout = async () => {
  const csrfToken = getCookie('XSRF-TOKEN')
  axios
    .post('http://localhost:80/logout', {
      headers: {
        'X-XSRF-TOKEN': decodeURIComponent(csrfToken)
      },
      withCredentials: true
    })
    .then(router.push('/login'))
}

解决方法

1. 修正登出请求的参数位置

axios.post的第二个参数是请求体数据,第三个参数才是配置项(含headers、withCredentials等)。当前登出代码把配置项放到了第二个参数的位置,导致headers未被正确识别,这是419错误的核心原因。

修正后的登出代码:

const logout = async () => {
  try {
    // 可选:登出前重新获取CSRF令牌,避免令牌过期
    await axios.get('http://localhost:80/sanctum/csrf-cookie');
    // 第二个参数传空对象(无请求体),第三个参数放配置
    await axios.post('http://localhost:80/logout', {}, {
      withCredentials: true
    });
    router.push('/login');
  } catch (err) {
    console.error('登出失败:', err);
  }
}

2. 简化axios配置,自动处理CSRF令牌

axios会自动从cookie中读取XSRF-TOKEN并添加到请求头,无需手动获取和设置。建议全局配置axios,减少重复代码:

// 在项目入口文件(如main.js)中配置
import axios from 'axios';

axios.defaults.baseURL = 'http://localhost:80';
axios.defaults.withCredentials = true; // 全局开启携带凭证

配置后,登录代码可简化为:

const login = async () => {
  error.value = null;
  const payload = {
    email: email.value,
    password: password.value
  };

  try {
    await axios.get('/sanctum/csrf-cookie');
    const response = await axios.post('/login', payload);
    if (response.data.error) {
      error.value = response.data.error;
    } else {
      router.push('/');
    }
  } catch (err) {
    error.value = '登录失败,请检查账号密码';
  }
}

3. 检查后端关键配置

  • cors.php:确保supports_credentials设为true,paths包含所有需要跨域的路由:
    'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'],
    'supports_credentials' => true,
    
  • .env:确认会话和Sanctum的域名配置正确(本地开发示例):
    SESSION_DOMAIN=localhost
    SANCTUM_STATEFUL_DOMAINS=localhost:5173 # 你的Vue项目端口
    
  • fortify.php:确保禁用视图,适配SPA:
    'views' => false,
    'features' => [
      Features::login(),
      Features::logout(),
      // 其他需要的功能
    ],
    

4. 验证API路由的认证中间件

确保api/users/auth路由使用了auth:sanctum中间件:

Route::get('/api/users/auth', function () {
  return auth()->user();
})->middleware('auth:sanctum');

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 14:00:28