import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axiosInstance from "../utils/axiosInstance";
export const logoutUser = createAsyncThunk(
"users/logoutUser",
async (_, { rejectWithValue, dispatch }) => {
try {
const response = await axiosInstance.post("/users/logout");
return response.data;
} catch (error) {
console.log(error.response.status);
if (error.response.status === 401) {
try {
await dispatch(refreshUserToken());
const retryResponse = await dispatch(logoutUser());
return retryResponse;
} catch (refreshError) {
return rejectWithValue(refreshError.message);
}
} else {
return rejectWithValue(error.message);
}
}
}
);
export const refreshUserToken = createAsyncThunk(
"users/refreshUserToken",
async (_, { rejectWithValue }) => {
try {
const response = await axiosInstance.post("/users/refresh-token");
console.log("refreshToken->", response.data);
return response.data;
} catch (error) {
return rejectWithValue(error.message);
}
}
);
const initialState = {
user: {},
status: "idle",
error: null,
};
const userSlice = createSlice({
name: "user",
initialState,
reducers: {},
extraReducers(builder) {
builder
.addCase(logoutUser.pending, (state, action) => {
state.status = "loading";
})
.addCase(logoutUser.fulfilled, (state, action) => {
state.status = "success";
console.log("case f logout->", action.payload); // log statement
state.user = {};
})
.addCase(logoutUser.rejected, (state, action) => {
state.error = action.payload;
})
.addCase(refreshUserToken.pending, (state, action) => {
state.status = "loading";
})
.addCase(refreshUserToken.fulfilled, (state, action) => {
state.status = "success";
console.log("case f refreshToken->", action.payload); // log statement
})
.addCase(refreshUserToken.rejected, (state, action) => {
state.error = action.payload;
});
},
});
export const getUserState = (state) => state.user.status;
export const getUserError = (state) => state.user.error;
export const getUser = (state) => state.user.user;
export const {} = userSlice.actions;
export default userSlice.reducer;
下面是我的axios实例.
const axiosInstance = axios.create({
baseURL: "http://localhost:8082/api",
withCredentials: true
});
我是Redux-Tools的新手,所以我很困惑.在logoutUser
cThunk中,我正在判断收到的错误代码是否为401(访问令牌已过期),然后我通过调用logoutUser
thunk中的refreshUserToken
thunk来请求刷新令牌,但这导致logoutThunk运行两次.
我该如何纠正这个问题?或者有更好的方法来处理使用DelivercThunks刷新 token ?
注意:我使用cookie来发送和接收来自服务器的访问和刷新令牌.