使用 React Native 和 Redux 刷新 OAuth 令牌

Posted

技术标签:

【中文标题】使用 React Native 和 Redux 刷新 OAuth 令牌【英文标题】:OAuth token refresh with React Native and Redux 【发布时间】:2018-01-20 15:25:05 【问题描述】:

我是 React Native 的新手,我遇到的第一个障碍是在访问令牌过期时刷新它。基本实现是有一个访问令牌和一个刷新令牌。访问令牌过期并在授权标头中发送刷新令牌以刷新访问令牌。基于this SO post,我实现了一个中间件,在每次API调用期间检查我们的访问令牌是否即将到期。如果是这样,它会启动一个动作创建者,该动作创建者会调用 API 来刷新并确认新的访问令牌。我在这里只展示了刷新调用,以免事情过于复杂。

问题是,检测到需要刷新的同一个中间件也会受到刷新调用本身的影响,这会导致无限循环并最终超出调用堆栈大小。我想知道是否有人能够帮助我找出解决此问题的方法,或者告诉我我很愚蠢并提供更好的整体解决方案。非常感谢任何指导。谢谢!

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】:

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

动作文件

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

中间件

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);
      );
  

【讨论】:

以上是关于使用 React Native 和 Redux 刷新 OAuth 令牌的主要内容,如果未能解决你的问题,请参考以下文章

使用 react-redux 与 react-native 连接时的不变违规

React native 和 redux 仍然无法正常工作

React Native - 使用 react-navigation 和 react-redux 在屏幕之间切换时数据丢失

React-native 和 Redux 健康的方式来调用 props 更改的操作

Wix React-Native-Navigation v2 和 redux-persist

使用 React Native / Redux 和 Firebase 保持身份验证