3

So I'm using React with React-Router.

I have a onEnter hook which checks if the user is authenticates yes/no and executes the desired action.

export function requireAuth(nextState, replaceState) {
  if (!isAuthenticated()) {
    if (!Storage.get('token')) replaceState(null, '/login');

    return delegate().then(() => replaceState(null, nextState.location.pathname));
  }

  if (nextState.location.pathname !== nextState.location.pathname) {
    return replaceState(null, nextState.location.pathname);
  }
}

When the token is expired I call a delegate function which looks like:

export function delegate() {
  const refreshToken = Storage.getJSON('token', 'refresh_token');

  return getData(endpoint)
      .then(res => {
        Storage.set('token', JSON.stringify({
          access_token: res.data.access_token,
          refresh_token: refreshToken,
        }));
      });
}

The delegate function indeed refresh the tokens in the localStorage. But the requests after the replaceState are not using the updated token, but the previous one. I think this is a async issue, someone knows more about this?

Edit: The function where I use the token:

function callApi(method, endpoint, data) {
  return new Promise((resolve, reject) => {
    let headers = {
      'Accept': 'application/json',
      'X-API-Token': Storage.getJSON('token', 'access_token'),
    };

    const body = stringifyIfNeeded(data);
    const options = { method, headers, body };

    return fetch(endpoint, options)
      .then(response =>
        response.json().then(json => ({ json, response }))
      ).then(({ json, response }) => {
        if (!response.ok) {
          reject({ json, response });
        }

        resolve(json);
      }).catch((error, response) => {
        reject({ error, response });
      });
  });
}
guidsen
  • 2,333
  • 6
  • 34
  • 55
  • Can you share where you are using the token when making requests? – chapinkapa Dec 17 '15 at 15:16
  • @chapinkapa I've added the function that is executed to make requests. Check the headers ;). – guidsen Dec 17 '15 at 16:30
  • Is `Storage` asynchronous? – Bergi Dec 17 '15 at 22:04
  • Btw, you're using the fetch-api weirdly. Avoid the [`Promise` constructor antipattern](http://stackoverflow.com/q/23803743/1048572). This should just be `return fetch(endpoint, options).then(response => response.ok ? response.json() : response.json.then(error => {throw {error, response};}))` – Bergi Dec 17 '15 at 22:07
  • @Bergi Storage is just an simple implementation where I use the localStorage. – guidsen Dec 18 '15 at 17:01
  • There's too much magic going on to follow what happens in your code. You have global (or externally scoped) variables all over the place, `Storage` is used as a service locator, instead of a storage abstraction. As it is now, it's nearly impossible to understand what's causing the problem. – Madara's Ghost Dec 20 '15 at 09:39

0 Answers0