

新闻资讯
技术学院本文介绍一种基于 useeffect 和 settimeout 的可靠方案,用于监听 jwt token 过期时间,并在过期瞬间触发登出与路由跳转,避免手动轮询或错误的时间比较逻辑。
在 React 应用中,仅依赖客户端时间判断 JWT 是否过期(如在
✅ 正确做法是:将 Token 过期监听提升至应用顶层(如 App.js),利用 useEffect + setTimeout 实现“精准倒计时登出” —— 即根据 exp 时间戳计算剩余毫秒数,设置一次性定时器,在到期时自动 dispatch logout 并导航至 /auth/login。
// App.jsx
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import jwt_decode from 'jwt-decode';
import { logout } from './features/auth/authSlice';
function App() {
const navigate = useNavigate();
const dispatch = useDispatch();
// 假设 token 存储在 auth.user.token 中(请按实际 state 结构调整)
const token = useSelector((state) => state.auth.user?.token);
useEffect(() => {
if (!token) return;
let timerRef = null;
try {
const decoded = jwt_decode(token);
const expiryMs = decoded.exp * 1000; // exp 是秒级时间戳
const nowMs = Date.now();
const timeout = expiryMs - nowMs;
const onExpire = () => {
dispatch(logout()); // 触发异步登出请求(可选)
navigate('/auth/login', { replace: true });
};
if (timeout > 0) {
timerRef = setTimeout(onExpire, timeout);
} else {
// Token 已过期,立即登出跳转
onExpire();
}
} catch (error) {
console.warn('Invalid or missing JWT token:', error);
dispatch(logout());
navigate('/auth/login', { replace: true });
}
// 清理定时器(组件卸载或 token 变更时)
return () => {
if (timerRef) clearTimeout(timerRef);
};
}, [dispatch, navigate, token]);
return (
{/* 你的 Router 配置,例如 */}
);
}
export default App;// ProtectedRoutes.jsx(精简安全版)
import { Navigate, Outlet } from 'react-router-dom';
import jwt_decode from 'jwt-decode';
export default function ProtectedRoutes() {
const token = sessionStorage.getItem('token');
if (!token) return ;
try {
const { exp } = jwt_decode(token);
if (Date.now() >= exp * 1000) {
sessionStorage.removeItem('token');
return ;
}
} catch {
sessionStorage.removeItem('token');
return ;
}
return ;
}通过顶层定时器 + 路由守卫双保险,即可实现平滑、可靠、用户体验友好的 Token 过期自动跳转机制。