Created
November 13, 2018 20:41
-
-
Save sregg/1659c0204192f2c6d24f2f2f799463bc to your computer and use it in GitHub Desktop.
Redux JWT Middleware
This file contains 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
export const jwtMiddleware: Middleware = ( | |
api: MiddlewareAPI<Dispatch, IRootState> | |
) => { | |
// add JWT access token to all request header if present | |
axios.interceptors.request.use((config: AxiosRequestConfig) => { | |
const authState = api.getState().auth; | |
if (authState.access) { | |
config.headers = { | |
...config.headers, | |
Authorization: `Bearer ${authState.access}`, | |
}; | |
} | |
return config; | |
}); | |
// refresh token if 401 TokenInvalid error | |
axios.interceptors.response.use(undefined, (error: any) => { | |
const authState = api.getState().auth; | |
const response = (error as AxiosError).response; | |
const originalRequest = (error as AxiosError).config; | |
if ( | |
authState.refresh && | |
response && | |
originalRequest && | |
response.status === 401 && | |
get(response, 'data.error.type') === 'InvalidToken' | |
) { | |
// if we're getting InvalidToken while trying to refresh, logout the user | |
if ( | |
originalRequest.url && | |
originalRequest.url.includes('token/refresh') | |
) { | |
logout()(api.dispatch, api.getState, undefined); | |
return Promise.reject(Error('Refresh token expired, logging user out')); | |
} | |
// make sure we are not already refreshing the token | |
if (!authState.refreshTokenPromise) { | |
// if not already refreshing, start the refreshing process | |
// and add the original request after | |
return refreshToken(authState.refresh, api.dispatch).then(() => | |
axios(originalRequest) | |
); | |
} else { | |
// if already refreshing, add this other request at the end of the chain | |
// (i.e. refresing + previous rquests) | |
return authState.refreshTokenPromise.then(() => | |
axios(originalRequest) | |
); | |
} | |
} | |
return Promise.reject(error); | |
}); | |
return next => action => { | |
return next(action); | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment