Last active
February 3, 2023 14:02
-
-
Save robsontenorio/d1e56c5bc5bc391ba0791be77419a68c to your computer and use it in GitHub Desktop.
[OAUTH2][KEYCLOAK] Auto refresh token for @nuxtjs/auth module
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
const strategy = 'keycloak' | |
export default function ({ app }) { | |
const { $axios, $auth } = app | |
if (!$auth.loggedIn || !$auth.strategies[strategy]) | |
return | |
const options = $auth.strategies.keycloak.options | |
let token = $auth.getToken(strategy) | |
let refreshToken = $auth.getRefreshToken(strategy) | |
if (!token || !refreshToken) | |
return | |
// calculate timeout before token expiration (75% from expiration time) | |
const tokenParsed = decodeToken.call(this, token) | |
let refreshInterval = (tokenParsed.exp * 1000 - Date.now()) * 0.75 | |
// Limit 10 seconds (avoid self attack) | |
if (refreshInterval < 10000) { | |
refreshInterval = 10000 | |
} | |
// keep refreshing token before expiration time | |
let refresher = setInterval(async function () { | |
try { | |
const response = await $axios.post(options.access_token_endpoint, | |
encodeQuery({ | |
refresh_token: refreshToken.replace(options.token_type + ' ', ''), | |
client_id: options.client_id, | |
grant_type: 'refresh_token' | |
}) | |
) | |
token = options.token_type + ' ' + response.data.access_token | |
refreshToken = options.token_type + ' ' + response.data.refresh_token | |
$auth.setToken(strategy, token) | |
$auth.setRefreshToken(strategy, refreshToken) | |
$axios.setToken(token) | |
} catch (error) { | |
$auth.logout() | |
throw new Error('Erro while refreshing token') | |
} | |
}, refreshInterval) | |
} | |
// Properly encode data | |
function encodeQuery (queryObject) { | |
return Object.keys(queryObject) | |
.map( | |
key => | |
encodeURIComponent(key) + '=' + encodeURIComponent(queryObject[key]) | |
) | |
.join('&') | |
} | |
// Decode JWT token | |
function decodeToken (str) { | |
str = str.split('.')[1]; | |
str = str.replace('/-/g', '+'); | |
str = str.replace('/_/g', '/'); | |
switch (str.length % 4) { | |
case 0: | |
break; | |
case 2: | |
str += '=='; | |
break; | |
case 3: | |
str += '='; | |
break; | |
default: | |
throw 'Invalid token'; | |
} | |
str = (str + '===').slice(0, str.length + (str.length % 4)); | |
str = str.replace(/-/g, '+').replace(/_/g, '/'); | |
str = decodeURIComponent(escape(atob(str))); | |
str = JSON.parse(str); | |
return str; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
[email protected]