Как мне автоматически обновить JWT в Redux без прерывания асинхронного потока? - PullRequest
0 голосов
/ 11 сентября 2018

Описание высокого уровня

У меня есть приложение React / redux / Electron, которое использует Google Oauth.Я хочу иметь возможность обновлять токен доступа автоматически, когда он истекает.Я исследовал это и решил его частично успешно, используя промежуточное ПО, но в некоторых ситуациях мое решение дает ошибку.

Я реализовал промежуточное ПО обновления, которое запускается при каждом действии API.Он проверяет, истек ли токен доступа или скоро истечет.Если это так, то вместо отправки полученного действия он отправляет действие обновления токена и ставит в очередь любые другие действия до получения нового токена доступа.После этого он отправляет все действия в своей очереди.

Однако один из моих создателей действий выглядит примерно так:

function queryThreads(params) {
  return async (dispatch) => {
    const threads = await dispatch(fetchThreads(params))
    const newPageToken = threads.payload.nextPageToken
  }
}

Когда промежуточное ПО обновления не запускается из-за того, что токен не установленне истекает, threads.payload будет определено здесь, и все будет работать как положено.

Однако, когда промежуточное программное обеспечение обновления запустится, threads.payload будет undefined, потому что dispatch, кажется, разрешается сзначение действия обновления токена, а не действия fetchThreads.

Как мне убедиться, что токен обновляется (и обновляется в state / localStorage), fetchThreads отправляется собновленный токен и переменной threads присваивается разрешенное значение правильного Обещания?

Ссылки на код проекта

Это мое промежуточное ПО обновления .Она была вдохновлена ​​ этой статьей kmmbvnr .

Это создатель действия обновления токена .

Это строка в моем создателе действия queryThreads , которая выдает, когда токен должен обновиться (threads.payload равно undefined).

Это редуктор, в котором я обновляю состояние в ответ на обновление токена.

Это промежуточное ПО, где я обновляю localStorage в ответ на обновление токена.

1 Ответ

0 голосов
/ 12 сентября 2018

Похоже, что я решил проблему, переписав промежуточное программное обеспечение для обновления следующим образом:

function createRefreshMiddleware() {
  const postponedRSAAs = [];
  return ({ dispatch, getState }) => {
    const rsaaMiddleware = apiMiddleware({ dispatch, getState });
    return next => action => {
      if (isRSAA(action)) {
        try {
          const auth = JSON.parse(localStorage.getItem('auth'));
          const { refresh_token: refreshToken } = auth;
          const expirationTime = jwtDecode(auth.id_token).exp * 1000;
          const isAccessTokenExpiring =
            moment(expirationTime) - moment() < 300000;

          if (refreshToken && isAccessTokenExpiring) {
            postponedRSAAs.push(action);
            if (postponedRSAAs.length === 1) {
              return rsaaMiddleware(next)(
                dispatch(() => attemptTokenRefresh(refreshToken))
              ).then(() => {
                const postponedRSAA = postponedRSAAs.pop();
                return dispatch(postponedRSAA);
              });
            }
            return rsaaMiddleware(next)(action);
          }
          return rsaaMiddleware(next)(action);
        } catch (e) {
          console.log(e);
          return next(action);
        }
      }
      return next(action);
    };
  };
}

export default createRefreshMiddleware();

Теперь отложенное действие всегда будет связано с действием обновления токена, поэтому у нас нетпроблема разрешения первоначального обещания с неправильным значением;плюс это более лаконично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...