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

React.js中Cookie过期未自动登出问题:路由切换无拦截

问题:Cookie过期后导航路由未自动登出,仅刷新页面才触发跳转

我有一个privateroute.js文件,用于路由权限和token状态校验,功能基本正常,但存在一个问题:即使Cookie过期,导航到受保护路由时不会自动登出,只有刷新页面才会跳转到登录页。

示例场景

即使内存中已无有效Cookie,从localhost:3000导航到localhost:3000/dashboard/analytics仍会被允许访问,但刷新页面后会立即跳转到login页面。

原代码

PrivateRoute.js

const ProtectedRoute = ({ component: Component, ...rest }) => {

const cookies = new Cookies();
const [authenticated, setAuthenticated] = useState(null);
const navigate = useNavigate();
const user = cookies.get("authToken");
const _id=cookies.get("xyz");
useEffect(async() => {
let as=null;
const cookies = new Cookies();


if (user) {
    const config = {
        headers: {
            "Content-Type": "application/json",
            'Authorization':`Bearer ${user}`,
        },
    };
    try{
      const {data}=await axios.post(
        `/api/auth/Veri`,
      {
        _id
      },
      config
      );
      
      if(data.email){
        setAuthenticated(true);
      }
      else{
         
         navigate("authentication/card/login");
      }
    }
    catch(error){
      
      ast=false;
      
      navigate("authentication/card/login");
    }
}
else {
  ast=false;
  setAuthenticated(false);
  navigate("authentication/card/login");
}
 }
  , []);

 useEffect(()=>{
if(authenticated==false){
  navigate("authentication/card/login");
}
}, []);

return (
authenticated ? <Outlet/> : null
)
 }
   export default ProtectedRoute;

Layout.js(路由文件)

<Route element={<PrivateRoutes/>}>
  <Route element={<MainLayout />}>
  {/*Dashboard*/}
  <Route path="/" element={<Dashboard />} />
  <Route path="dashboard/analytics" element={<Analytics />} />
  <Route path="dashboard/crm" element={<Crm />} />
  <Route path="dashboard/saas" element={<Saas />} />
  <Route path="dashboard/e-commerce" element={<Ecommerce />} />
 
  </Route>
</Route>

问题原因

  1. Cookie读取时机错误:user和_id仅在组件初始化时读取一次,后续路由导航时不会获取最新的Cookie状态;
  2. useEffect依赖缺失:第一个useEffect依赖数组为空,仅在组件挂载时执行一次校验,路由切换时不会重新触发;
  3. 状态变化未监听:第二个useEffect依赖为空,authenticated状态变化时无法触发导航逻辑;
  4. 异步回调不规范:直接将async作为useEffect回调函数,可能导致内存泄漏或逻辑异常。

修复方案

修改ProtectedRoute.js,确保每次路由切换时重新校验权限,并正确响应状态变化:

import { useState, useEffect } from 'react';
import { useNavigate, useLocation, Outlet } from 'react-router-dom';
import Cookies from 'js-cookie';
import axios from 'axios';

const ProtectedRoute = () => {
  const [authenticated, setAuthenticated] = useState(null);
  const navigate = useNavigate();
  const location = useLocation();

  useEffect(() => {
    const validateAuth = async () => {
      // 每次校验都读取最新的Cookie
      const authToken = Cookies.get("authToken");
      const userId = Cookies.get("xyz");

      // 无Cookie直接标记未认证
      if (!authToken || !userId) {
        setAuthenticated(false);
        return;
      }

      try {
        const config = {
          headers: {
            "Content-Type": "application/json",
            'Authorization': `Bearer ${authToken}`,
          },
        };

        const { data } = await axios.post(
          `/api/auth/Veri`,
          { _id: userId },
          config
        );

        // 根据接口返回判断认证状态
        if (data.email) {
          setAuthenticated(true);
        } else {
          setAuthenticated(false);
        }
      } catch (error) {
        // 请求失败直接标记未认证
        setAuthenticated(false);
      }
    };

    validateAuth();
  }, [location.pathname, navigate]); // 路由变化时重新执行校验

  // 监听认证状态变化,未认证时跳转登录页
  useEffect(() => {
    if (authenticated === false) {
      navigate("authentication/card/login");
    }
  }, [authenticated, navigate]);

  // 认证状态未确定时返回null,避免闪烁;认证通过则渲染子路由
  return authenticated ? <Outlet /> : null;
};

export default ProtectedRoute;

关键修改点

  • 使用useLocation监听路由路径变化,每次导航时重新执行权限校验;
  • 将Cookie读取逻辑放到校验函数内部,确保每次都获取最新的Cookie状态;
  • 修复async直接作为useEffect回调的问题,内部定义异步函数再调用;
  • 给两个useEffect添加正确的依赖数组,确保状态变化和路由变化时触发相应逻辑;
  • 统一处理authenticated状态,将导航逻辑集中到状态监听的useEffect中,避免逻辑分散。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 21:15:44