How to logout automatically when session expires while using createAsyncThunk and axios (withcredential) option using react and redux toolkit?

Viewed 93

I am trying to logout the user when the session expires after a certain period of time. I am using redux-toolkit with react for my API calls and, hence, using the createAsyncThunk middleware for doing so.

I have around 60 API calls made in maybe 20 slices throughout my application. Also, there is a async function for logout too that is fired up on the button click. Now the problem that I am facing is that if the session expires, I am not able to logout the user automatically. If I had to give him the message, then I had to take up that message from every api call and make sure that every screen of mine has a logic to notify the Unautherised message.

I did check a method called Polling that calls an API after a certain given time. And I believe that this is not a very efficient way to handle this problem.

**Here is a little code that will help you understand how my API calls are being made in the slices of my application. **

// Here is the custom created api that has axios and withcredentials value

import axios from "axios";

const api = axios.create({
  baseURL:
    process.env.NODE_ENV === "development" ? process.env.REACT_APP_BASEURL : "",
  headers: {
    "Content-Type": "application/json",
  },
  withCredentials: true,
});

export default api;


// My Logout Function!!


export const logoutUser = createAsyncThunk(
  "userSlice/logoutUser",
  async (thunkAPI) => {
    try {
      const response = await api.get("/api/admin/logout");
      if (response.status === 200) {
        return response.data;
      } else {
        return thunkAPI.rejectWithValue(response.data);
      }
    } catch (e) {
      return thunkAPI.rejectWithValue(e.response.data);
    }
  }
);

I want to dispatch this function whenever there is a response status-code is 401 - Unauthorised. But I don't want to keep redundant code for all my other API calls calling this function. If there is a middleware that might help handle this, that would be great, or any solution will be fine.

// Rest of the APIs are called in this way.

..........

export const getStatus = createAsyncThunk(
  "orgStat/getStatus",
  async (thunkAPI) => {
    try {
      const response = await api.get("/api/admin/orgstat");
      if (response.status === 200) {
        return response.data;
      } else {
        return thunkAPI.rejectWithValue(response.data);
      }
    } catch (e) {
      return thunkAPI.rejectWithValue(e.response.data);
    }
  }
);

const OrgStatusSlice = createSlice({
  name: "orgStat",
  initialState,
  reducers: {
    .......
  },
  extraReducers: {
    [getStatus.pending]: (state) => {
      state.isFetching = true;
    },
    [getStatus.rejected]: (state, { payload }) => {
      state.isFetching = false;
      state.isError = true;
      state.isMessage = payload.message;
    },
    [getStatus.fulfilled]: (state, { payload }) => {
      state.isFetching = false;
      state.data = payload.data;
    },
  },
});

.......

If needed any more clearence please comment I will edit the post with the same.

Thank You!!

0 Answers
Related