React JS实现用户无活动时自动登出(Token失效)
React实现用户无活动自动登出功能
你已经完成了登录表单和基础的登录/登出功能,要实现用户无活动时自动登出,可以按以下步骤来做:
核心思路
通过监听用户的交互事件(如鼠标移动、键盘输入)重置超时定时器,当用户超过设定时长无操作时,触发登出逻辑并清空Token。
具体实现步骤
1. 在全局组件中管理超时逻辑
在根组件(比如App.js)或专门的AuthProvider组件中,添加监听用户活动和管理定时器的逻辑:
import { useEffect, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { setLogout } from './path/to/authSlice'; import { useNavigate } from 'react-router-dom'; // 定义无活动超时时间(示例为30分钟,单位毫秒) const INACTIVITY_TIMEOUT = 30 * 60 * 1000; function App() { const dispatch = useDispatch(); const navigate = useNavigate(); const { token } = useSelector(state => state.auth); const [timeoutId, setTimeoutId] = useState(null); // 重置超时定时器 const resetTimeout = () => { if (timeoutId) clearTimeout(timeoutId); const id = setTimeout(() => { // 超时触发登出 dispatch(setLogout()); navigate('/login'); }, INACTIVITY_TIMEOUT); setTimeoutId(id); }; // 监听用户活动事件 useEffect(() => { if (!token) return; // 添加多种交互事件监听 const events = ['mousemove', 'keydown', 'click', 'scroll', 'touchstart']; events.forEach(event => window.addEventListener(event, resetTimeout)); // 初始化启动定时器 resetTimeout(); // 清理函数:移除监听并清除定时器 return () => { events.forEach(event => window.removeEventListener(event, resetTimeout)); if (timeoutId) clearTimeout(timeoutId); }; }, [token, timeoutId, dispatch, navigate]); // ... 其他组件渲染逻辑 } export default App;
2. 登录逻辑适配
登录成功后,全局的useEffect会自动检测到token变化并启动定时器,无需额外修改现有登录函数。如果需要更精准控制,也可以在登录成功后手动调用resetTimeout:
const login = async (values, onSubmitProps) => { const loggedInResponse = await fetch("http://localhost:5001/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(values), }); const loggedIn = await loggedInResponse.json(); onSubmitProps.resetForm(); if (loggedIn) { dispatch( setLogin({ user: loggedIn.user, token: loggedIn.token, }) ); navigate("/dashboard"); // 可选:手动触发一次定时器重置 resetTimeout(); } };
3. 登出时的双重保险
现有setLogout reducer无需修改,因为全局useEffect会在token变为null时自动清除定时器和事件监听,确保资源被正确释放。
注意事项
- 可根据业务需求调整
INACTIVITY_TIMEOUT的时长,比如设置为15分钟或1小时。 - 移动端场景可保留
touchstart事件监听,提升兼容性。 - 如果使用React Router,跳转登录页优先用
navigate而非window.location.href,保持单页应用路由一致性。
内容的提问来源于stack exchange,提问作者Muhammad Shahzaib
相关产品推荐
相关产品推荐

