React JS中使用localStorage实现会话 无token时跳转登录页的实现方法
React 基于localStorage实现会话校验、未登录自动跳转方案
你可以通过路由层统一校验 + Axios响应拦截器兜底两层逻辑实现需求,具体实现步骤如下:
1. 第一步:封装路由保护组件(全局拦截未登录访问)
不管是类组件还是函数组件页面,只要是需要登录才能访问的路由,都用这个高阶组件包裹,进入路由前就会校验token有效性,没有就直接跳转到登录页。
函数组件实现(适配React Router v6常用版本)
import { Navigate } from 'react-router-dom'; // 路由保护高阶组件 const RequireAuth = ({ children }) => { const token = localStorage.getItem('token'); // 可以在这里加token过期校验逻辑,比如存储的时候同时存过期时间,这里判断是否过期 if (!token) { // 跳转登录页,同时可以带参数方便登录后跳回原页面,state里传提示信息 return <Navigate to="/login" state={{ message: '请先登录' }} replace />; } return children; };
路由配置用法
// 路由配置里用RequireAuth包裹需要登录的页面 <Routes> <Route path="/login" element={<LoginPage />} /> {/* 下面是需要登录的页面 */} <Route path="/dashboard" element={ <RequireAuth> <Dashboard /> </RequireAuth> } /> <Route path="/personal" element={ <RequireAuth> <PersonalCenter /> </RequireAuth> } /> </Routes>
登录页接收提示信息展示
// LoginPage组件里获取提示并展示 import { useLocation } from 'react-router-dom'; function LoginPage() { const location = useLocation(); const tipMsg = location.state?.message; return ( <div> {tipMsg && <div className="tip">{tipMsg}</div>} {/* 其余登录表单逻辑 */} </div> ) }
2. 第二步:封装Axios拦截器兜底处理token失效情况
避免出现token在页面停留期间过期、后端返回401未授权的情况,统一处理跳转:
// 新建utils/request.js,统一封装axios实例 import axios from 'axios'; import { createBrowserHistory } from 'history'; const history = createBrowserHistory(); const request = axios.create({ baseURL: '你的接口基础地址' }); // 请求拦截器:统一加token,不用每个请求单独写 request.interceptors.request.use( (config) => { const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `token ${token}`; } return config; }, (error) => Promise.reject(error) ); // 响应拦截器:统一处理401未授权 request.interceptors.response.use( (response) => response.data, (error) => { if (error.response?.status === 401) { // token无效/过期,清理本地存储跳转登录 localStorage.removeItem('token'); history.push('/login', { message: '请先登录' }); } return Promise.reject(error); } ); export default request;
后续所有请求直接用封装好的request实例即可,不用每个请求单独拼接headers:
// 类组件请求示例 import request from 'utils/request'; componentDidMount() { request.get('你的接口地址') .then(res => { /* 处理响应 */ }) } // 函数组件请求示例 useEffect(() => { request.get('你的接口地址') .then(res => { console.log(res.Diet) }) }, [])
3. 可选优化:添加token过期校验
你可以在登录存储token的时候同时存储过期时间,校验的时候同时判断是否过期:
// 登录成功存储逻辑 localStorage.setItem('token', response.data.token); // 假设token有效期24小时,存储过期时间戳 localStorage.setItem('token_expire', Date.now() + 24 * 60 * 60 * 1000); // 校验token是否有效逻辑 const isTokenValid = () => { const token = localStorage.getItem('token'); const expire = localStorage.getItem('token_expire'); return token && expire && Date.now() < Number(expire); }
在RequireAuth组件和请求拦截器里用isTokenValid()代替直接判断token是否存在即可。
内容的提问来源于stack exchange,提问作者vivek kn
相关产品推荐
相关产品推荐

