Skip to content

Instantly share code, notes, and snippets.

@sregg
Created November 13, 2018 20:41
Show Gist options
  • Save sregg/1659c0204192f2c6d24f2f2f799463bc to your computer and use it in GitHub Desktop.
Save sregg/1659c0204192f2c6d24f2f2f799463bc to your computer and use it in GitHub Desktop.
Redux JWT Middleware
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