From 245d291b75dc489ae9112922b2ba0fb64b45fc99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Fromme?= Date: Sun, 29 Sep 2019 18:57:40 +0200 Subject: [PATCH] WIP Implement token refreshing --- .../Resources/Private/Assets/js/api/index.js | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/api/index.js diff --git a/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/api/index.js b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/api/index.js new file mode 100644 index 00000000..12f1a1c8 --- /dev/null +++ b/public/typo3conf/ext/ep_theme/Resources/Private/Assets/js/api/index.js @@ -0,0 +1,77 @@ +// See https://www.techynovice.com/setting-up-JWT-token-refresh-mechanism-with-axios/ + +import axios from 'axios'; + +const authenticatedClient = axios.create({ + headers: { + 'Authentication': 'Bearer ' + sessionStorage.getItem('token') + } +}); + +authenticatedClient.interceptors.response.use( + response => response, + error => { + const errorResponse = error.response; + if (isTokenExpiredError(errorResponse)) { + return resetTokenAndReattemptRequest(error) + } + return Promise.reject(error) + } +); + +function isTokenExpiredError (errorResponse) { + if (errorResponse.config.code !== 401) { + return false + } + + return errorResponse.message.match(/expired/); +} + +let isAlreadyFetchingAccessToken = false; +let subscribers = []; + +async function resetTokenAndReattemptRequest (error) { + try { + const { response: errorResponse } = error; + const refreshToken = await getRefreshToken(); + if (!refreshToken) { + return Promise.reject(error); + } + const retryOriginalRequest = new Promise(resolve => { + addSubscriber(authToken => { + errorResponse.config.headers.Authorization = 'Bearer ' + authToken; + resolve(axios(errorResponse.config)); + }); + }); + if (!isAlreadyFetchingAccessToken) { + isAlreadyFetchingAccessToken = true; + axios({ + method: 'post', + url: ``, + data: { + refresh_token: refreshToken + } + }).then(response => { + if (!response.data) { + return Promise.reject(error); + } + const newToken = response.data.refresh_token; + saveRefreshToken(newToken); + isAlreadyFetchingAccessToken = false; + onAccessTokenFetched(newToken); + }); + } + return retryOriginalRequest; + } catch (err) { + return Promise.reject(err); + } +} + +function onAccessTokenFetched(access_token) { + subscribers.forEach(callback => callback(access_token)); + subscribers = []; +} + +function addSubscriber(callback) { + subscribers.push(callback); +}