首页 文章

使用React Native和Redux刷新OAuth令牌

提问于
浏览
0

我是React Native的新手,我遇到的第一个障碍就是当它到期时刷新我的访问令牌 . 基本实现是存在访问令牌和刷新令牌 . 访问令牌到期,刷新令牌在Authorization标头内发送,以刷新访问令牌 . 基于this SO post我实施了一个中间件,在每个API调用期间检查我们的访问令牌是否即将到期 . 如果是这样,它将启动一个动作创建者,该动作创建者进行API调用以刷新并确认新的访问令牌 . 我这里只展示了刷新调用,以免过于复杂化 .

PROBLEM 是检测到需要刷新的同一中间件也被刷新调用本身击中,这导致无限循环并最终超过调用堆栈大小 . 我想知道是否有人能帮助我找到解决方法,或者告诉我,我是愚蠢的,并提供更好的整体解决方案 . 任何指导都非常感谢 . 谢谢!

function auth({ dispatch, getState }) {
      return next => action => {
        if (typeof action === 'function') {
          // Check expiration of our token
          if (tokenIsExpired(getState)) {
            console.log('Our access token will expire in less than 30s, refreshing');
            // Make sure we are not already refreshing the access token
            if (!getState().core.refreshTokenIsLoading) {
              return next(dispatch(refreshAccessTokenFlow())).then(() => next(action));
            } else {
              // Take promise from state and act after it
              return getState().core.refreshAccessTokenFlow.then(() => next(action));
            }
          }
        }
        return next(action);
      }
    }

export function refreshAccessTokenFlow() {
  return (dispatch) => {
    return dispatch(refreshAccessToken())
      .then((didRefresh) => {
        console.log('refresh access token returned');
        return Promise.resolve();
      })
      .catch(error => {
        console.log('refresh access token failed: ' + error);
        return Promise.reject(error);
      });
  }
}

1 回答

  • 0

    例如,您可以在需要访问令牌的操作中传递元数据,然后在中间件检查中传递元数据,或者您需要根据该元数据验证令牌 .

    Action file

    // My Team
    export function fetchStuffWithOAuthStart(userId) {
      return {
        type: USER_FETCH_STUFF_WITHOUT_OAUTH_START,
        payload: { userId },
        meta: {
          oauth: true,
        }
    };
    

    Middleware

    function auth({ dispatch, getState }) {
          return next => action => {
            if (typeof action === 'function') {
              // Check here or you need to validate the token
              if (!action.meta || !action.meta.oauth) {
                return next(action);
              }
    
              // Check expiration of our token
              if (tokenIsExpired(getState)) {
                console.log('Our access token will expire in less than 30s, refreshing');
                // Make sure we are not already refreshing the access token
                if (!getState().core.refreshTokenIsLoading) {
                  return next(dispatch(refreshAccessTokenFlow())).then(() => next(action));
                } else {
                  // Take promise from state and act after it
                  return getState().core.refreshAccessTokenFlow.then(() => next(action));
                }
              }
            }
            return next(action);
          }
        }
    
    export function refreshAccessTokenFlow() {
      return (dispatch) => {
        return dispatch(refreshAccessToken())
          .then((didRefresh) => {
            console.log('refresh access token returned');
            return Promise.resolve();
          })
          .catch(error => {
            console.log('refresh access token failed: ' + error);
            return Promise.reject(error);
          });
      }
    }
    

相关问题