jeffbski / redux-logic

Redux middleware for organizing all your business logic. Intercept actions and perform async processing.
MIT License
1.81k stars 107 forks source link

Handling oAuth refresh token #121

Open dominikkurbiel opened 6 years ago

dominikkurbiel commented 6 years ago

Hello,

I have oAuth authorization in my app. But I'm confused with the implementation of refresh token service.

At the moment I created instance of axios and apply to logic middleware. After login I use my AuthService to set headers with authorization token to my axios instance, and set tokens to localStorage.

Then I create axios interceptor to handle 401 error and send request to get new token, after success response I change authorization header and resend original request with new token. It works fine, but it is not connected to redux-logic now. Request is called, and I get the response but not as redux action.

It looks like:

  1. GET_CURRENT_USER_START //token expired
  2. GET_CURRENT_USER_ERROR // here I want to call GET_CURRENT_USER_START action again after received new token

My interceptor:

let isAlreadyFetchingAccessToken = false;

const httpClient = axios.create({
  baseURL: config.APP_URL,
});

httpClient.interceptors.response.use(function (response) {
  return response
}, function (error) {
  const { config, response: { status } } = error;
  const originalRequest = config;

  if (status === 401) {
    if (!isAlreadyFetchingAccessToken) {
      isAlreadyFetchingAccessToken = true;

      return axios.post(refreshTokenUrl)
      .then((res) => {
        isAlreadyFetchingAccessToken = false;
        AuthService.saveAuth(res.data);
        originalRequest.headers['Authorization'] = 'Bearer ' + res.data.access_token;
        httpClient(originalRequest); // here request is calling but not as redux action
      });
    }
  }
  return Promise.reject(error)
});

export default httpClient;

How to handle oAuth2 refresh token in redux-logic?

Perfect scenario:

  1. User hit button to receive data from api. // GET_USERS_START
  2. Token is expired.
  3. Browser get 401 error (Unauthorized). // GET_USERS_ERROR
  4. Redux-logic automatically handle that, and make request for new token.
  5. New token is received, headers of my axios instance is changed to new autorization token.
  6. GET_USERS_START action is called automatically.
skbolton commented 6 years ago

It would be good to see your logic that is doing a call with this http client. On the surface things look fine but would need to see the call site.