如何在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
相关产品推荐
相关产品推荐

