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

如何在React中利用Context API实现Token过期自动登出用户

实现React Token过期自动登出的三种方案

针对你的需求,我们可以从路由切换检查、Axios拦截器全局处理、定时自动检测三个维度实现Token过期自动登出,以下是具体实现步骤:


一、路由切换时自动检查Token过期

利用React Router的useLocation监听路由变化,每次路由切换时校验Token有效性,过期则触发登出。修改你的AuthProvider组件:

import { useReducer, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import Jwt_Decode from 'jwt-decode';

const initialstate = {
  user: null,
};
if (localStorage.getItem("JWT_Token")) {
  const jwt_Token_decoded = Jwt_Decode(localStorage.getItem("JWT_Token"));
  if (jwt_Token_decoded.exp * 1000 < Date.now()) {
    localStorage.clear();
  } else {
    initialstate.user = jwt_Token_decoded;
  }
}

const AuthContext = createContext({
  user: null,
  login: (userData) => {},
  logout: () => {},
});

const AuthReducer = (state, action) => {
  switch (action.type) {
    case "LOGIN":
      return {
        ...state,
        user: action.payload,
      };
    case "LOGOUT":
      return {
        ...state,
        user: null,
      };
    default:
      return state;
  }
};
    
const AuthProvider = (props) => {
  const [state, dispatch] = useReducer(AuthReducer, initialstate);
  const location = useLocation();

  const login = (userData) => {
    localStorage.setItem("JWT_Token", userData.token);
    dispatch({
      type: "LOGIN",
      payload: userData,
    });
    // 登录成功后设置过期定时器
    setupTokenExpiryTimer(userData.token);
  };

  const logout = () => {
    localStorage.clear();
    dispatch({ type: "LOGOUT" }); // 修复原代码dispatch参数错误
  };

  // 路由切换时检查Token状态
  useEffect(() => {
    checkTokenExpiry();
  }, [location]);

  // 通用Token过期检查函数
  const checkTokenExpiry = () => {
    const token = localStorage.getItem("JWT_Token");
    if (!token) return;
    const decoded = Jwt_Decode(token);
    if (decoded.exp * 1000 < Date.now()) {
      logout();
    }
  };

  // 设置Token过期倒计时定时器
  const setupTokenExpiryTimer = (token) => {
    const decoded = Jwt_Decode(token);
    const expiryTime = decoded.exp * 1000 - Date.now();
    if (expiryTime > 0) {
      setTimeout(() => {
        logout();
        alert("Token已过期,已自动登出");
      }, expiryTime);
    }
  };
    
  return (
    <AuthContext.Provider
      value={{ user: state.user, login, logout }}
      {...props}
    />
  );
};
    
export { AuthContext, AuthProvider };

二、Axios全局拦截器处理Token过期

在你的Axios实例中添加请求和响应拦截器,统一处理Token校验和后端返回的过期状态:

import axios from "axios";
import Jwt_Decode from 'jwt-decode';

const BASE_URL = "https://jsonplaceholder.typicode.com";

const api = axios.create({
  baseURL: BASE_URL,
  headers: {
    "Content-Type": "Application/json",
  },
});

// 请求拦截器:携带Token并检查有效性
api.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem("JWT_Token");
    if (token) {
      const decoded = Jwt_Decode(token);
      if (decoded.exp * 1000 < Date.now()) {
        localStorage.clear();
        window.location.href = '/login';
      } else {
        config.headers['Access-token'] = token;
      }
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器:处理后端返回的401过期状态
api.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      localStorage.clear();
      window.location.href = '/login';
    }
    return Promise.reject(error);
  }
);

export default api;

如果需要在拦截器中直接调用AuthContext的logout函数,可以将Axios实例的创建逻辑封装到自定义Hook中,通过useContext获取上下文方法。


三、页面停留时定时自动检查

该逻辑已整合到上述setupTokenExpiryTimer函数中,用户登录成功后会根据Token的过期时间设置定时器,到期自动触发登出,无需额外配置。


总结

三种方案结合可全面覆盖Token过期场景:

  • 路由切换检查:处理页面内跳转时的Token有效性
  • Axios拦截器:覆盖所有请求场景,响应后端过期提示
  • 定时检测:用户停留在同一页面时自动触发登出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:00:38