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

Next.js中如何正确解码JWT Token并使用其中的用户数据

问题根源排查
  • 状态初始值错误:你给user状态设置的初始值是空数组[],JavaScript中空数组属于truthy值,三元判断user ? xxx : xxx时未登录状态会触发真分支,将非字符串的空数组传入jwt-decode,直接抛出invalid token错误,该错误未被捕获时会导致全屏白屏,不会执行else分支逻辑。
  • 缺少异常捕获:jwt-decode接收到无效输入(非JWT格式字符串、空值、篡改后的token)时会同步抛出错误,你当前的调用逻辑没有做异常捕获。
  • Cookie存取逻辑不严谨:登录成功后你用JSON.stringify包裹字符串类型的token存入Cookie,读取时如果没有对应做JSON.parse,拿到的会是带引号的字符串,也会导致解码失败。
修复步骤

1. 修正状态初始值

将user状态的初始值改为null,符合未登录状态下的空值预期:

// 替换原有声明
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const [loggedIn, setLoggedIn] = useState(false);

2. 封装安全解码工具函数

统一添加异常捕获,避免无效输入导致的崩溃:

import jwtDecode from 'jwt-decode';

const safeDecodeJwt = (token) => {
  // 先校验输入格式
  if (!token || typeof token !== 'string' || token.split('.').length !== 3) {
    return null;
  }
  try {
    return jwtDecode(token);
  } catch (err) {
    // 解码失败直接返回空,不抛出错误
    return null;
  }
};

3. 修正登录/退出登录逻辑

登录存储逻辑:

移除不必要的JSON.stringify,直接存储字符串格式的token:

// 登录成功分支的代码修正
if (data && !data.error) {
  setUser(data.token);
  setLoggedIn(true);
  // 直接存token字符串,不需要JSON.stringify
  Cookies.set("user-info", data.token);
  router.push("/");
}

退出登录逻辑:

重置所有相关状态,清空Cookie:

const handleLogout = () => {
  setUser(null);
  setLoggedIn(false);
  Cookies.remove("user-info");
  // 可选:跳转到登录页
  router.push("/login");
};

4. 初始化时校验Cookie中的token

页面加载时从Cookie读取token需要做格式校验,避免无效值赋值给user:

useEffect(() => {
  const savedToken = Cookies.get("user-info");
  const decoded = safeDecodeJwt(savedToken);
  if (decoded) {
    setUser(savedToken);
    setLoggedIn(true);
  }
}, []);
业务中使用解码数据的方法

后续需要获取用户ID等JWT内置信息时,直接调用封装好的工具函数即可:

// 示例:获取用户ID
const decodedUser = safeDecodeJwt(user);
const userId = decodedUser?.id;

// 你原有打印逻辑的正确写法
decodedUser ? console.log(decodedUser) : console.log("login");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 09:54:08