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

Laravel Sanctum+React SPA登出后仍可访问受保护路由问题求助

Laravel Sanctum + React SPA:登出后仍可访问受保护路由,Cookie自动更新问题

我用Laravel Sanctum和React开发简单SPA时遇到了棘手问题:执行任意前端操作时laravel_session和XSRF-TOKEN Cookie会自动更新,导致/logout路由失效——就算控制台提示“CSRF token mismatch.”,还是能访问后端受保护路由。

问题重现流程

  • 无Cookie状态下调用/login授权成功,可访问受保护路由(忽略/dashboard调用,已在cors.php中拦截,仅用于跳转);
  • 成功调用/api/cars获取车辆数据;
  • 调用/logout使当前Token失效,预期后续无法访问/api/cars;
  • 但实际后续仍能正常访问/api/cars,即便Token已失效。

核心异常:每次前端操作都会自动更新laravel_session和XSRF-TOKEN Cookie,但控制台看不到登出后有调用/login的记录。我怀疑是组件渲染的问题,但找不到具体位置,附上所有React组件代码,求技术帮助!


可能的排查方向与解决方案

1. 检查Sanctum登出逻辑是否正确

确保Laravel后端的/logout路由彻底销毁会话:

// 根据路由配置选择api.php或web.php
Route::post('/logout', function (Illuminate\Http\Request $request) {
    Auth::guard('web')->logout();
    $request->session()->invalidate();
    $request->session()->regenerateToken();
    
    return response()->json(['message' => 'Logged out successfully']);
})->middleware('auth:sanctum');

登出时必须同时执行销毁守卫、失效会话、重新生成CSRF Token三个操作,避免旧会话残留导致授权状态未清除。

2. 前端登出后强制清除Cookie并重置请求实例

React端登出后,需手动清除相关Cookie,并重置请求库的默认配置:

import axios from 'axios';
import Cookies from 'js-cookie';
import { useNavigate } from 'react-router-dom';

const handleLogout = async () => {
    try {
        await axios.post('/logout');
        // 清除Sanctum相关Cookie
        Cookies.remove('laravel_session');
        Cookies.remove('XSRF-TOKEN');
        // 重置Axios默认Headers
        axios.defaults.headers.common['X-XSRF-TOKEN'] = '';
        // 跳转至登录页
        navigate('/login');
    } catch (error) {
        console.error('Logout failed:', error);
    }
};

如果不主动清除Cookie,浏览器会自动携带旧会话Cookie,导致Sanctum仍识别为已授权状态。

3. 排查请求拦截器的自动重试逻辑

检查Axios拦截器是否存在自动重试或重新获取Token的逻辑,这会导致登出后Cookie被重新激活:

// 错误示例:拦截器自动重试触发Cookie更新
axios.interceptors.response.use(
    response => response,
    async error => {
        if (error.response.status === 419) {
            // 自动获取CSRF Token会更新Cookie,重建会话
            await axios.get('/sanctum/csrf-cookie');
            // 重试请求会携带新Cookie,导致授权状态恢复
            return axios(error.config);
        }
        return Promise.reject(error);
    }
);

需在拦截器中添加用户状态判断,登出后禁用这类自动重试逻辑,避免Cookie被意外更新。

4. 检查组件挂载时的自动请求

排查全局Layout、路由守卫等组件,是否在未判断登录状态的情况下自动发起授权相关请求:

// 错误示例:组件挂载时无条件获取CSRF Token
import { useEffect } from 'react';
import axios from 'axios';

const Layout = ({ children }) => {
    useEffect(() => {
        // 未判断登录状态,登出后仍会更新Cookie
        axios.get('/sanctum/csrf-cookie');
    }, []);
    
    return <div>{children}</div>;
};

需添加用户状态判断,仅在未登录时调用/sanctum/csrf-cookie接口。

5. 验证Sanctum与CORS配置

检查Laravel配置文件:

  • config/sanctum.php的stateful数组需包含SPA域名;
  • config/cors.php的supports_credentials需设为true;
  • 环境变量SESSION_DOMAIN需与SPA域名一致(例如.yourdomain.com)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:40:25