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
相关产品推荐
相关产品推荐

