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

graph LR subgraph Application A([Front]) end subgraph SSO D(FirebaseAuth) end F(Utilisateur) --> A A --Délégation authentification-->D D --OK Délivre un token --> A

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

sequenceDiagram Utilisateur->>Front: Demande de connection Front->>FireBase: Délégation Authentification FireBase->>FireBase: Authentification FireBase->>Front: Token Valable 1h Utilisateur->>Front: Utilisation de l'application Front->>Back: Utilisation de Endpoint (GET/POST...) Back->>FireBase: Vérification du Token FireBase->>Back: Token valide Back->>Front: Ok Réponse 200 Utilisateur->>Front: Utilisation de l'application (après 1h) Front->>Back: Utilisation de Endpoint (GET/POST...) Back->>FireBase: Vérification du Token FireBase->>Back: Token expiré Back->>Front: Erreur Réponse 401 Unauthorized Front->>Utilisateur: Message d'erreur

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é.