Created
          February 10, 2019 21:20 
        
      - 
      
- 
        Save mrnkr/663977a2cf81687f4bbe5e704eaa7137 to your computer and use it in GitHub Desktop. 
    Redux middleware to exchange a refresh token prior to any request if the access token is expired
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | async function refresh(dispatch: Dispatch, getState: () => MyState): Promise<void> { | |
| const { auth: { authenticated, refresh_token: refresh } } = getState(); | |
| if (!authenticated) | |
| return; | |
| try { | |
| const { access_token, refresh_token, token_type } = await (async () => { | |
| const res = await fetch(`${baseUrl}/oauth2/token`, { | |
| method: 'POST', | |
| headers: { | |
| "Authorization": `Basic ${btoa(`${client.name}:${client.secret}`)}`, | |
| "Content-Type": "application/json" | |
| }, | |
| body: JSON.stringify({ | |
| "grant_type": "refresh_token", | |
| "refresh_token": refresh | |
| }) | |
| }); | |
| return res.json(); | |
| })(); | |
| const token_expiration = new Date(Date.now() + TOKEN_DURATION_MINUTES * 60000).toISOString(); | |
| dispatch({ type: AuthActions.REFRESH, payload: { access_token, refresh_token, token_type, token_expiration } }); | |
| } catch (err) { | |
| dispatch({ type: AuthActions.ERROR }); | |
| } | |
| } | |
| // Redux middleware to keep tokens alive :D | |
| // Apply before thunk if using thunk 👈 | |
| export const assertAuth: Middleware<Dispatch, MyState> = | |
| ({ dispatch, getState }) => next => async action => { | |
| const { auth: { authenticated, token_expiration } } = getState(); | |
| // Prevent unnecessary calls and infinite loops | |
| if (!authenticated || action.type === AuthActions.REFRESH) | |
| return next(action); | |
| const now = new Date(); | |
| const expiration = new Date(token_expiration as string); | |
| const isExpired = now > expiration; | |
| if (isExpired) | |
| await refresh(dispatch, getState); | |
| return next(action); | |
| } | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment