React.js登录后获取展示当前用户遇阻:Token存储异常及数据获取问题
解决React+Redux登录后获取用户信息及Token存储问题
看起来你现在遇到两个核心问题:一是登录请求后users变量为undefined导致无法存储Token,二是Redux State里存储的是JWT Token而非用户对象,所以拿不到用户名等具体数据。咱们一步步来解决:
1. 修复Token存储时的undefined问题
先看你的login Action里的这段代码:
.then((response) => { const users = response.data dispatch(loginSuccess(users)) localStorage.setItem('jwt', users.auth_token) console.log('users', users) // undefined })
这里users为undefined,大概率是后端接口的返回结构和你预期的不一致。你需要先确认后端/logIn接口返回的具体格式:
- 打开浏览器开发者工具的Network标签,找到登录请求,查看Response的具体内容
- 如果后端返回的是类似
{ "auth_token": "xxx", "user": { "username": "xxx", "name": "xxx" } },那你应该正确解构数据:
.then((response) => { const { auth_token, user } = response.data // 根据实际返回结构调整 dispatch(loginSuccess(user)) // 把用户对象传给loginSuccess localStorage.setItem('jwt', auth_token) console.log('user info', user) console.log('token', auth_token) })
如果后端只返回了JWT Token(比如直接返回字符串),那你需要调整代码:
.then((response) => { const token = response.data // 这里需要解析Token获取用户信息,后面会讲 const user = parseJwt(token) dispatch(loginSuccess(user)) localStorage.setItem('jwt', token) })
2. 从JWT Token中解析用户信息
JWT Token是Base64编码的,你可以通过解码Payload部分来获取用户信息(注意:不要在前端验证Token的有效性,验证交给后端,但解析内容是安全的)。添加一个解析Token的工具函数:
// 工具函数:解析JWT Token const parseJwt = (token) => { try { return JSON.parse(atob(token.split('.')[1])) } catch (e) { return null } }
然后在登录成功后调用这个函数,把解析后的用户对象存入Redux State。
3. 修正Redux Reducer的状态更新
你的Reducer里把action.payload同时赋值给user和users,而且初始State里没有users字段,这会导致状态混乱。调整Reducer:
const initialState: UserState = { user: null, // 初始化为null更合理 loading: false, error: '', isAuthenticated: false, // 移除多余的users字段,除非你需要存储多个用户 } const UserReducer = (state = initialState, action: UserActions) => { switch (action.type) { case LOGIN_USER_SUCCESS: return { ...state, loading: false, user: action.payload, // 这里存储解析后的用户对象 isAuthenticated: true, error: '', } case LOGOUT: return { ...state, isAuthenticated: false, user: null, // 移除users字段,保持状态简洁 } // 别忘了处理FETCH_USER_REQUEST和FETCH_LOGIN_FAILURE的情况! case FETCH_USER_REQUEST: return { ...state, loading: true, error: '' } case FETCH_LOGIN_FAILURE: return { ...state, loading: false, error: action.payload, isAuthenticated: false, user: null } default: return state } }
注意:你之前的Reducer没有处理FETCH_USER_REQUEST和FETCH_LOGIN_FAILURE的action,这会导致loading状态一直不对,必须补上。
4. 在组件中获取用户信息
现在你的Logout组件里可以直接从Redux State获取用户信息了:
const user = useSelector((state: AppState) => state.user.user) // 现在user是包含用户名的对象,比如user.username或者user.name console.log('当前用户', user?.username)
额外注意事项
- 确保后端返回的JWT Token的Payload部分包含你需要的用户字段(比如username、name、email等),如果没有,需要调整后端接口的Token生成逻辑
- 登录成功后,建议把Token放在axios的请求头里,方便后续接口请求携带身份信息:
// 登录成功后设置axios默认头 axios.defaults.headers.common['Authorization'] = `Bearer ${auth_token}`
- 页面刷新时,需要从localStorage读取Token,重新解析用户信息并同步到Redux State,可以在App组件的useEffect里处理:
useEffect(() => { const token = localStorage.getItem('jwt') if (token) { const user = parseJwt(token) dispatch(loginSuccess(user)) axios.defaults.headers.common['Authorization'] = `Bearer ${token}` } }, [dispatch])
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

