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

React+TypeScript中JWT解析及用户数据全局存储的正确方案

React + TypeScript 解析JWT自定义Claim并全局存储方案

1. 解决JWT解析的TypeScript类型问题

首先定义自定义Token的类型,让TypeScript识别你的自定义Claim字段:

// src/types/auth.ts
export interface UserToken {
  sub: string; // JWT标准字段(用户ID)
  exp: number; // 过期时间戳
  username: string; // 自定义用户名字段
  role: 'admin' | 'user'; // 自定义角色字段,用联合类型限制可选值
}

// 封装解析Token的函数,带错误捕获
import jwtDecode from 'jwt-decode';

export const decodeAuthToken = (token: string): UserToken | null => {
  try {
    return jwtDecode<UserToken>(token);
  } catch (err) {
    console.error('无效Token,解析失败:', err);
    return null;
  }
};

解析时指定UserToken类型后,就能直接访问username、role等字段,不会再出现类型报错。

2. 用React Context实现全局用户状态管理(解决类型问题)

直接封装类型安全的Context,避免使用时的类型歧义:

// src/contexts/UserContext.tsx
import { createContext, useContext, ReactNode, useState, useEffect } from 'react';
import { UserToken, decodeAuthToken } from '../types/auth';
import Cookies from 'js-cookie';

// 定义Context的完整类型
interface UserContextType {
  user: UserToken | null;
  logout: () => void;
}

// 创建Context并设置符合类型的默认值,避免组件调用时报错
const UserContext = createContext<UserContextType>({
  user: null,
  logout: () => {},
});

// 全局Provider组件
export const UserProvider = ({ children }: { children: ReactNode }) => {
  const [user, setUser] = useState<UserToken | null>(null);

  // 初始化时从Cookie读取Token并解析
  useEffect(() => {
    const token = Cookies.get('Authorization');
    if (token) {
      setUser(decodeAuthToken(token));
    }
  }, []);

  // 登出逻辑:清除Cookie和用户状态
  const logout = () => {
    Cookies.remove('Authorization');
    setUser(null);
  };

  return (
    <UserContext.Provider value={{ user, logout }}>
      {children}
    </UserContext.Provider>
  );
};

// 封装自定义Hook,简化组件调用
export const useUser = () => {
  const context = useContext(UserContext);
  // 强制要求在Provider范围内使用,避免误用
  if (!context) {
    throw new Error('useUser必须在UserProvider组件内部调用');
  }
  return context;
};

3. 在App中注入全局Provider

// src/App.tsx
import { UserProvider } from './contexts/UserContext';
import Profile from './components/Profile';
import Navbar from './components/Navbar';

function App() {
  return (
    <UserProvider>
      <Navbar />
      <Profile />
    </UserProvider>
  );
}

export default App;

4. 组件中直接访问用户数据

比如个人资料组件:

// src/components/Profile.tsx
import { useUser } from '../contexts/UserContext';

const Profile = () => {
  const { user } = useUser();

  if (!user) {
    return <div>请先登录</div>;
  }

  return (
    <div>
      <h2>个人资料</h2>
      <p>用户名:{user.username}</p>
      <p>角色:{user.role}</p>
    </div>
  );
};

export default Profile;

注意事项

  • 安装依赖:npm install jwt-decode js-cookie,类型包:npm install @types/js-cookie --save-dev
  • 解析Token时必须捕获异常,防止无效Token导致页面崩溃
  • 可以在useEffect中检查exp字段,自动处理Token过期的登出逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:06:07