Blog
Refresh Token usando Axios Interceptors

Refresh Token usando Axios Interceptors

Entiende qué son los Interceptors y qué es un Refresh Token.

17 de junho de 2021

Esta es una republicación del post del blog de Vinnicius Gomes – Senior Frontend Engineer en Zappts.

Refresh token diagram

Axios es un cliente HTTP que funciona tanto en el browser como en Node.Js. La biblioteca es básicamente una API que sabe interactuar tanto con XMLHttpRequest como con la interfaz HTTP de Node. Esto significa que el mismo código utilizado para hacer peticiones Ajax en el browser también funciona del lado del servidor.

Hablemos de Interceptors

Los Interceptors son, como el propio nombre dice, interceptores. En Axios podemos utilizarlos para ejecutar alguna función antes de que la Request y/o Response sea iniciada.

Segue un ejemplo:

// Agregando un interceptor de Request
axios.interceptors.request.use(function (config) {
   // Haz algo antes de que la petición sea enviada
   return config;
 }, function (error) {
   // Haz algo con el error de la petición
   return Promise.reject(error);
 });
// Agregando un interceptor de Response
axios.interceptors.response.use(function (response) {
   // Cualquier código de estado que esté dentro de 2xx hará que esta función se active
   // Haz algo con los datos de respuesta
   return response;
 }, function (error) {
   // Cualquier código de estado que esté fuera de 2xx hará que esta función se active
   // Haz algo con el error de respuesta
   return Promise.reject(error);
 });

Puedes encontrar este ejemplo en la propia documentación de Axios a través de este enlace.

Ahora que ya sabes qué es un interceptor, ¡vamos a lo que importa!

Si no sabes qué es un Refresh Token, lee esto aquí.

Entonces vamos a comenzar nuestro Refresh Token, vamos a crear un archivo llamado api.js:

import axios from "axios";

const api = axios.create({
 headers: {
   "Access-Control-Allow-Origin": "*",
   client_id: process.env.CLIENT_ID,
 },
 baseURL: process.env.API_URL,
});

export default api;

En este archivo resumidamente creamos la configuración inicial para usar Axios en la aplicación.

Ahora, vamos a crear un interceptor para las Responses que vamos a recibir de la API dentro de este archivo, algo parecido a esto:

import axios from "axios";

const api = axios.create({
 headers: {
   "Access-Control-Allow-Origin": "*",
   client_id: process.env.CLIENT_ID,
 },
 baseURL: process.env.API_URL,
});

api.interceptors.response.use(
 (response) => {
   return response;
 },
 async function (error) {
   const access_token = localStorage.getItem("access_token");
   if (error.response.status === 401 && access_token) {
     const response = await refreshToken(error);
     return response;
   }
   return Promise.reject(error);
 }
);

export default api;

Creamos un interceptor utilizando la constante api, verificamos si el estado del error devuelto por la API fue 401, y si el usuario tiene un access_token. Luego llamamos a la función refreshToken() que vamos a crear ahora:

async function refreshToken(error) {
 return new Promise((resolve, reject) => {
   try {
     const refresh_token = localStorage.getItem("refresh_token");
     const header = {
       "Content-Type": "application/json",
       Authorization: process.env.AUTHORIZATION,
     };
     const parameters = {
       method: "POST",
       headers: header,
     };
     const body = {
       grant_type: "refresh_token",
       refresh_token,
     };
     axios
       .post(
         process.env.API_URL + "/refreshtoken",
         body,
         parameters
       )
       .then(async (res) => {
         localStorage.setItem("access_token", res.data.access_token);
         localStorage.setItem("refresh_token", res.data.refresh_token);
         // Hacer algo si se realiza el refresh token
         return resolve(res);
       })
       .catch((err) => {
         // Hacer algo si no se realiza el refresh token
         return reject(error);
       });
   } catch (err) {
     return reject(err);
   }
 });
};

En esta función estamos haciendo una nueva llamada al End Point que es responsable por el refresh token, y en caso de que nos devuelva éxito crearemos un flujo para actualizar el token dentro de nuestra aplicación donde está el comentario.

Si nuestra petición de refresh token ha dado algún error, podemos desconectar al usuario añadiendo una función donde está el comentario en la línea 30.

¡Y eso es básicamente todo!