React如何保持登录状态
使用本地存储(localStorage/sessionStorage)
将用户登录凭证(如token)存储在浏览器的localStorage或sessionStorage中。localStorage持久化存储,关闭浏览器后仍存在;sessionStorage仅在当前会话有效,关闭标签页后清除。
// 登录成功后存储token
localStorage.setItem('authToken', 'your_token_here');
// 应用初始化时检查token
const token = localStorage.getItem('authToken');
if (token) {
// 验证token有效性,更新应用状态
}
使用Context API管理全局状态
通过React的Context API共享登录状态,避免逐层传递props。结合useReducer或useState管理用户认证状态。
// 创建AuthContext
const AuthContext = createContext();
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = (token, userData) => {
localStorage.setItem('authToken', token);
setUser(userData);
};
const logout = () => {
localStorage.removeItem('authToken');
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
}
// 在组件中使用
const { user, login, logout } = useContext(AuthContext);
使用HTTP Only Cookie
后端设置HttpOnly Cookie存储token,防止XSS攻击窃取。前端每次请求自动携带Cookie,无需手动处理存储。
// 后端示例(Node.js/Express)
res.cookie('authToken', 'your_token_here', {
httpOnly: true,
secure: true, // 仅HTTPS
maxAge: 86400000 // 过期时间
});
定时刷新Token
为避免token过期导致用户被迫重新登录,实现静默刷新机制。在token临近过期时,使用refresh token获取新token。
// 检查token过期时间并刷新
function checkTokenExpiry() {
const token = localStorage.getItem('authToken');
if (isTokenExpiringSoon(token)) {
fetch('/api/refresh-token', {
method: 'POST',
credentials: 'include'
}).then(res => res.json())
.then(data => localStorage.setItem('authToken', data.newToken));
}
}
// 定时检查(如每小时一次)
setInterval(checkTokenExpiry, 3600000);
路由守卫(Protected Routes)
通过高阶组件或自定义钩子限制未登录用户访问特定路由,自动跳转到登录页。
function PrivateRoute({ component: Component, ...rest }) {
const { user } = useContext(AuthContext);
return (
<Route
{...rest}
render={props =>
user ? <Component {...props} /> : <Redirect to="/login" />
}
/>
);
}
服务端渲染(SSR)兼容
在Next.js等框架中,结合getServerSideProps或中间件验证服务端登录状态,确保首屏渲染时已同步认证状态。
// Next.js示例
export async function getServerSideProps(context) {
const { req } = context;
const token = req.cookies.authToken;
if (!token) {
return { redirect: { destination: '/login' } };
}
return { props: { user: await verifyToken(token) } };
}






