You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS中刷新页面时如何利用localStorage的JWT更新登录状态

解决React页面刷新时用localStorage的JWT恢复登录状态的方案

我来帮你搞定这个页面刷新后登录状态丢失的问题——这在React单页应用里是个非常常见的场景。核心思路就是在应用初始化阶段,自动从localStorage读取JWT并验证有效性,然后同步更新你的登录状态state。下面是具体的实现步骤,结合你的场景来拆解:

1. 先写一个JWT验证工具函数

首先我们需要一个函数来检查localStorage里的token是否存在、是否未过期。毕竟存了token不代表它还能用,过期的token是无效的:

const isTokenValid = () => {
  // 从localStorage获取token
  const token = localStorage.getItem('jwtToken');
  if (!token) return false;

  try {
    // 解析JWT的payload部分(注意:这里只是前端校验,后端还是会再验证的)
    const decodedPayload = JSON.parse(atob(token.split('.')[1]));
    // 把当前时间转成秒,和token的过期时间对比
    const currentTimestamp = Date.now() / 1000;
    return decodedPayload.exp > currentTimestamp;
  } catch (err) {
    // 解析失败说明token格式有问题,直接返回无效
    return false;
  }
};

2. 在根组件初始化时检查并更新登录状态

把检查逻辑放在你的根组件(比如App.js)的useEffect里,因为页面刷新后根组件会重新挂载,这个useEffect会自动执行一次:
假设你的登录状态是用useState管理的,比如:

const [isLoggedIn, setIsLoggedIn] = useState(false);
const [currentUser, setCurrentUser] = useState(null);

然后添加这个useEffect:

useEffect(() => {
  const syncAuthState = () => {
    const tokenIsValid = isTokenValid();
    if (tokenIsValid) {
      // token有效,更新登录状态
      setIsLoggedIn(true);
      // 顺便把用户信息解析出来存入state(可选,根据你的token结构调整)
      const token = localStorage.getItem('jwtToken');
      const decodedPayload = JSON.parse(atob(token.split('.')[1]));
      setCurrentUser(decodedPayload.user);
    } else {
      // token无效或者不存在,清空localStorage并保持未登录状态
      localStorage.removeItem('jwtToken');
      setIsLoggedIn(false);
      setCurrentUser(null);
    }
  };

  syncAuthState();
}, []); // 空依赖数组确保只在组件挂载时执行一次

3. 同步登录/登出操作的状态与localStorage

要保证登录和登出时,state和localStorage是同步的,避免出现不一致的情况:

  • 登录成功时:
const handleLogin = async (loginFormData) => {
  try {
    const response = await fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(loginFormData)
    });
    const { token } = await response.json();
    // 把token存入localStorage
    localStorage.setItem('jwtToken', token);
    // 更新登录状态和用户信息
    setIsLoggedIn(true);
    const decodedPayload = JSON.parse(atob(token.split('.')[1]));
    setCurrentUser(decodedPayload.user);
  } catch (err) {
    console.error('登录失败:', err);
  }
};
  • 登出时:
const handleLogout = () => {
  // 清空localStorage里的token
  localStorage.removeItem('jwtToken');
  // 重置登录状态
  setIsLoggedIn(false);
  setCurrentUser(null);
  // 如果用了react-router,跳转到登录页
  // navigate('/login');
};

4. 优化:给请求加拦截器处理token失效

如果你的项目用了axios这类请求库,可以加个响应拦截器,当后端返回401(未授权)时,自动清空状态并跳转到登录页,避免用户停在无效状态:

import axios from 'axios';

// 请求拦截器:自动给请求带上token
axios.interceptors.request.use(
  (config) => {
    const token = localStorage.getItem('jwtToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器:处理401状态
axios.interceptors.response.use(
  (response) => response,
  (error) => {
    if (error.response?.status === 401) {
      localStorage.removeItem('jwtToken');
      setIsLoggedIn(false);
      setCurrentUser(null);
      // 跳转到登录页
      navigate('/login');
    }
    return Promise.reject(error);
  }
);

这样一来,页面刷新后,应用会自动检查localStorage里的JWT是否有效,有效就把登录状态更新回state,用户就不会看到“未登录”的状态了,同时请求也能正常带上token完成授权。

内容的提问来源于stack exchange,提问作者Maruth51

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 15:07:28