Retry requests if they fail with 401

Resolves JWT token timeout handling #23
This commit is contained in:
Matthias 2020-07-17 07:09:52 +02:00
parent a2098a65e8
commit d115f8efb0
2 changed files with 70 additions and 55 deletions

View File

@ -10,10 +10,13 @@ export const api = axios.create({
api.interceptors.request.use( api.interceptors.request.use(
(config) => { (config) => {
const custconfig = config; const custconfig = config;
// Merge custconfig dicts const token = userService.getAccessToken();
custconfig.headers = { ...config.headers, ...userService.getAuthHeader() }; if (token) {
// Do something before request is sent // Merge custconfig dicts
// console.log(custconfig) custconfig.headers = { ...config.headers, ...{ Authorization: `Bearer ${token}` } };
// Do something before request is sent
// console.log(custconfig)
}
return custconfig; return custconfig;
}, },
(error) => Promise.reject(error), (error) => Promise.reject(error),
@ -26,9 +29,32 @@ api.interceptors.response.use(
console.log(err); console.log(err);
if (err.response && err.response.status === 401) { if (err.response && err.response.status === 401) {
console.log('Dispatching refresh_token...'); console.log('Dispatching refresh_token...');
userService.refreshToken(); return userService
.refreshToken()
.then((token) => {
// Retry original request with new token
const { config } = err;
config.headers.Authorization = `Bearer ${token}`;
return new Promise((resolve, reject) => {
axios
.request(config)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(error);
});
});
})
.catch((error) => {
console.log('No new token received');
console.log(error);
});
// maybe redirect to /login if needed ! // maybe redirect to /login if needed !
} else if (err.response && err.response.status === 500) { }
if (err.response && err.response.status === 500) {
console.log('Bot seems to be offline...'); console.log('Bot seems to be offline...');
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

View File

@ -1,6 +1,6 @@
import axios from 'axios'; import axios from 'axios';
const AUTH_REF_TOKEN = 'auth_ref_token'; const AUTH_REFRESH_TOKEN = 'auth_ref_token';
const AUTH_ACCESS_TOKEN = 'auth_access_token'; const AUTH_ACCESS_TOKEN = 'auth_access_token';
const AUTH_API_URL = 'auth_api_url'; const AUTH_API_URL = 'auth_api_url';
const apiBase = '/api/v1'; const apiBase = '/api/v1';
@ -8,21 +8,21 @@ const apiBase = '/api/v1';
export default { export default {
apiBase, apiBase,
AUTH_API_URL, AUTH_API_URL,
setAPIUrl(apiurl) { setAPIUrl(apiurl: string): void {
localStorage.setItem(AUTH_API_URL, JSON.stringify(apiurl)); localStorage.setItem(AUTH_API_URL, JSON.stringify(apiurl));
}, },
setAccessToken(token) { setAccessToken(token: string): void {
localStorage.setItem(AUTH_ACCESS_TOKEN, JSON.stringify(token)); localStorage.setItem(AUTH_ACCESS_TOKEN, JSON.stringify(token));
}, },
setRefreshTokens(refreshToken) { setRefreshTokens(refreshToken: string): void {
localStorage.setItem(AUTH_REF_TOKEN, JSON.stringify(refreshToken)); localStorage.setItem(AUTH_REFRESH_TOKEN, JSON.stringify(refreshToken));
}, },
logout() { logout(): void {
console.log('Logging out'); console.log('Logging out');
localStorage.removeItem(AUTH_REF_TOKEN); localStorage.removeItem(AUTH_REFRESH_TOKEN);
localStorage.removeItem(AUTH_ACCESS_TOKEN); localStorage.removeItem(AUTH_ACCESS_TOKEN);
localStorage.removeItem(AUTH_API_URL); localStorage.removeItem(AUTH_API_URL);
}, },
@ -47,33 +47,36 @@ export default {
} }
}, },
refreshToken() { refreshToken(): Promise<string> {
console.log('Refreshing token...'); console.log('Refreshing token...');
const token = JSON.parse(localStorage.getItem(AUTH_REF_TOKEN) || '{}'); const token = JSON.parse(localStorage.getItem(AUTH_REFRESH_TOKEN) || '{}');
const apiurl = this.getAPIUrl(); return new Promise((resolve, reject) => {
console.log(apiurl); axios
axios .post(
.post( `${this.getAPIUrl()}/${apiBase}/token/refresh`,
`${this.getAPIUrl()}/${apiBase}/token/refresh`, {},
{}, {
{ headers: { Authorization: `Bearer ${token}` },
headers: { Authorization: `Bearer ${token}` }, },
}, )
) .then((response) => {
.then((result) => { if (response.data.access_token) {
if (result.data.access_token) { this.setAccessToken(response.data.access_token);
this.setAccessToken(result.data.access_token); // Return plain access token
} resolve(response.data.access_token);
}) }
.catch((err) => { })
console.error(err); .catch((err) => {
if (err.response && err.response.status === 401) { console.error(err);
// in case of errors when using the refresh token - logout. if (err.response && err.response.status === 401) {
this.logout(); // in case of errors when using the refresh token - logout.
} else if (err.response && (err.response.status === 500 || err.response.status === 404)) { this.logout();
console.log('Bot seems to be offline... - retrying later'); } else if (err.response && (err.response.status === 500 || err.response.status === 404)) {
} console.log('Bot seems to be offline... - retrying later');
}); reject(err);
}
});
});
}, },
loggedIn() { loggedIn() {
@ -85,25 +88,11 @@ export default {
return typeof apiUrl === 'object' ? '' : apiUrl; return typeof apiUrl === 'object' ? '' : apiUrl;
}, },
getAccessToken() { getAccessToken(): string {
return JSON.parse(localStorage.getItem(AUTH_ACCESS_TOKEN) || '{}'); return JSON.parse(localStorage.getItem(AUTH_ACCESS_TOKEN) || '{}');
}, },
getRefreshToken() { getRefreshToken() {
return JSON.parse(localStorage.getItem(AUTH_REF_TOKEN) || '{}'); return JSON.parse(localStorage.getItem(AUTH_REFRESH_TOKEN) || '{}');
},
getAuthHeader() {
let result = {};
const accessToken = this.getAccessToken();
if (accessToken) {
result = {
Authorization: `Bearer ${accessToken}`,
};
} else {
console.log('user not logged in');
}
return result;
}, },
}; };