FireBase – Axios – Refresh Token JWT !!
Bonjour à tous !! Aujourd'hui un article, qui comme son nom l'indique, va parler de FireBase, Axios et le refresh automatique du Token.
Pourquoi faire un article sur ce sujet ? Et bien je vous expose rapidement le petit soucis que j'ai rencontré, vous allez mieux comprendre. Et vu que des schémas valent mieux que de long discours.
Utilisation de FireBase Auth en tant que SSO
Un utilisateur veut se connecter à mon application SaaS. Il arrive sur la partie Front et n'est pas authentifié. Le Front délégue cette authentification à FireBase Auth. Une fois la connection de l'utilisateur établie, FireBase renvoi un Token JWT au Front et l'accès peut se faire.
Jusque là tous va bien. MAIS, car c'est là que le soucis intervient (ou plutôt 1 heure après). En effet, comme vous devez le savoir un Token JWT dispose d'une durée de validité, dans notre cas avec FireBase il s'agît d'une heure. Mais vous allez me dire : Ok, mais que se passe-t-il après cette période ?
Schéma lorsque le token expire
Un peu complexe et long à lire ce schéma. Mais il s'agît pourtant de l'utilisation classique d'un SSO et d'un Token JWT. Mais ce qu'il faut retenir ici c'est l'erreur de fin, un beau 401 et un token expiré.
Du coup, solution pour l'utilisateur un gros refresh de sa page et une obligation de se ré authentifier pour récupérer un token "neuf".
Solution pas ouf, voir même pas acceptable du point de vue expérience utilisateur.
Solution : Axios et le refresh Token
La solution est simple mais vu que j'ai un peu lutter pour la trouver et que je suis super sympa, je vous la partage !!
Il s'agît d'un intercepteur Axios. Voici celui que j'ai mis en place.
const api = 'Initialisation des appels vers votre API'
const auth = 'Initialisation authentification Firebase'
let refresh = false
api.interceptors.response.use(response => response, async requestOrigin => {
if (requestOrigin.response.status === 401 && !refresh) {
refresh = true
return await auth.currentUser?.getIdToken(true)
.then((response) => {
api.defaults.headers.Authorization = `Bearer ${response}`
}).then(() => {
requestOrigin.config.headers.Authorization =
api.defaults.headers.Authorization
return api.request(requestOrigin.config)
})
} else {
refresh = false
return requestOrigin
}
})
Quelques explications...
Une fois dans l'intercepteur, on test le status de la réponse et si le code retour est notre fameux 401, on lance tous simplement une demande de token pour l'utilisateur en cours. Une fois le nouveau token obtenu, on mets à jour notre api avec ce derniers pour les futurs appels mais aussi la requête d'origine qui a échouée pour la rejouer. Cela va éviter de faire remonter l'erreur à l'utilisateur.
Et voilà un petit article simple mais qui je l'espère vous a aidé.