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

如何使用Redux Toolkit自动获取API数据实现用户授权校验

使用Redux Toolkit实现全局用户授权状态管理

需求描述

我需要从/api/auth/profile接口获取token解析后的用户数据,以此判断用户是否授权,开放对应功能。要求网站加载时自动获取数据,且能在多页面复用,请问如何用Redux Toolkit实现?

我尝试过的代码

Redux Slice基础实现:

import { createSlice,createAsyncThunk } from "@reduxjs/toolkit";

export const fetchUserInfo = createAsyncThunk("fetchUserInfo", async () => {
  const res = await fetch("http://localhost:8800/api/auth/profile")
  return res.json()
})

const userInfo = createSlice({
  name:"userInfo",
  initialState:{
    data:null
  },
  extraReducers: (builder) => {
    builder.addCase(fetchUserInfo.fulfilled, (state,action) => {
      state.data = action.payload;
    })
  }
})

export default userInfo.reducer;

尝试过的触发方式:

import { fetchUserInfo } from '../../redux/userSlice';

 setTimeout(()=>{
    dispatch(fetchUserInfo())
    console.log("implemented")
  },1000)

另外试过RTK Query,但遇到Redux Store Provider与Api Provider冲突的问题。


解决方案

一、完善Redux Slice的状态管理

你的基础Slice缺少加载、错误状态的处理,以及授权状态的直接维护,补充后更便于页面判断:

import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";

export const fetchUserInfo = createAsyncThunk("userInfo/fetchUserInfo", async (_, { rejectWithValue }) => {
  try {
    const res = await fetch("http://localhost:8800/api/auth/profile", {
      credentials: 'include', // 若token存在Cookie中需添加;若存在localStorage,要在headers里带Authorization
      headers: {
        // 示例:token存在localStorage时添加
        // 'Authorization': `Bearer ${localStorage.getItem('token')}`
      }
    });
    if (!res.ok) throw new Error('获取用户信息失败');
    return await res.json();
  } catch (err) {
    return rejectWithValue(err.message);
  }
});

const userInfoSlice = createSlice({
  name: "userInfo",
  initialState: {
    data: null,
    loading: false,
    error: null,
    isAuthenticated: false // 直接维护授权状态,避免页面重复判断
  },
  reducers: {
    // 手动登出时清空状态
    logout: (state) => {
      state.data = null;
      state.isAuthenticated = false;
      state.error = null;
    }
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchUserInfo.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchUserInfo.fulfilled, (state, action) => {
        state.loading = false;
        state.data = action.payload;
        state.isAuthenticated = true; // 接口返回有效数据即视为已授权
      })
      .addCase(fetchUserInfo.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload;
        state.isAuthenticated = false; // 请求失败/未授权则标记为未登录
      });
  }
});

export const { logout } = userInfoSlice.actions;
export default userInfoSlice.reducer;

二、配置Redux Store

确保Store正确挂载这个reducer:

import { configureStore } from "@reduxjs/toolkit";
import userInfoReducer from './userSlice';

export const store = configureStore({
  reducer: {
    userInfo: userInfoReducer,
    // 其他项目reducer...
  }
});

三、全局自动触发用户信息获取

不要用setTimeout这种不可靠的方式,直接在App根组件的useEffect中触发:

import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { fetchUserInfo } from './redux/userSlice';

function App() {
  const dispatch = useDispatch();

  useEffect(() => {
    // 页面初始化时立即请求用户信息
    dispatch(fetchUserInfo());
  }, [dispatch]);

  return (
    // 你的路由和页面组件
  );
}

export default App;

四、多页面中使用授权状态

在任意组件中通过useSelector获取状态,快速判断授权情况:

import { useSelector } from 'react-redux';

function ProtectedComponent() {
  const { isAuthenticated, loading, data } = useSelector(state => state.userInfo);

  if (loading) return <div>加载中...</div>;
  if (!isAuthenticated) return <div>请先登录</div>;

  return (
    <div>欢迎你,{data.username}</div>
  );
}

解决RTK Query的Provider冲突问题

之前的冲突是因为RTK Query的Api Provider需要和Redux Store共用同一个Store,正确配置方式如下:

// api.js
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const userApi = createApi({
  reducerPath: 'userApi',
  baseQuery: fetchBaseQuery({ 
    baseUrl: 'http://localhost:8800/api/',
    credentials: 'include' // 或携带Authorization头,根据token存储方式选择
  }),
  endpoints: (builder) => ({
    getUserInfo: builder.query({
      query: () => 'auth/profile'
    })
  })
});

export const { useGetUserInfoQuery } = userApi;

// store.js
import { configureStore } from "@reduxjs/toolkit";
import { userApi } from './api';

export const store = configureStore({
  reducer: {
    [userApi.reducerPath]: userApi.reducer,
    // 其他reducer...
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(userApi.middleware)
});

// App.js
import { Provider } from 'react-redux';
import { store } from './redux/store';

function App() {
  return (
    <Provider store={store}>
      {/* 你的组件 */}
    </Provider>
  );
}

配置完成后,直接在组件中调用useGetUserInfoQuery()即可自动获取数据,无需额外的Api Provider。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:36:50