2017-08-12 13 views
0

React Nativeの新機能で、実行中の最初の障害の1つは、有効期限が切れたときにアクセストークンを更新することです。基本的な実装では、アクセストークンとリフレッシュトークンが存在します。アクセストークンが期限切れになり、リフレッシュトークンがAuthorizationヘッダー内で送信され、アクセストークンが更新されます。私は、API呼び出しのたびに私たちのアクセストークンが間もなく期限切れになっているかどうかをチェックするミドルウェアを実装していました(this)。そうであれば、新しいアクセストークンをリフレッシュして確認するためのAPI呼び出しを行うアクションクリエータを起動します。私は物事を過度に複雑化しないように、ここでリフレッシュコールを表示しました。React NativeとReduxを使用したOAuthトークンのリフレッシュ

問題番号は、リフレッシュの必要性を検出する同じミドルウェアがリフレッシュコール自体によってもヒットされ、ループが無限になり、最終的に呼び出しスタックサイズを超えてしまうことです。誰かがこれを回避する方法を見つけ出す手助けをすることができるか、私が愚かであり、より良い全体的な解決策を提供していると私に教えてくれるかどうか疑問に思っていました。どんな指導も大変ありがとうございます。ありがとうございました!

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

答えて

0

あなたは、例えば、トークン、その後ミドルウェアチェックにアクセスを必要とするアクションでメタデータを渡すことができます。また、そのメタデータに基づいてトークンを検証する必要があります。

アクションファイル

// 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); 
     }); 
    } 
} 
関連する問題