Skip to content

Instantly share code, notes, and snippets.

@danielbonifacio
Forked from Godofbrowser/axios.refresh_token.1.js
Last active September 11, 2023 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danielbonifacio/60f0491e5d6531b5c49f1bac466a1acc to your computer and use it in GitHub Desktop.
Save danielbonifacio/60f0491e5d6531b5c49f1bac466a1acc to your computer and use it in GitHub Desktop.
Configuração do serviço HTTP para renovar o token apenas uma vez em múltiplas chamadas. Criado para o curso Especialista React.js da AlgaWorks.
import axios from "axios";
import Service from "danielbonifacio-sdk/dist/Service";
import AuthService from "./Authorization.service";
const { REACT_APP_API_BASE_URL } = process.env;
if (REACT_APP_API_BASE_URL) Service.setBaseUrl(REACT_APP_API_BASE_URL);
Service.setRequestInterceptors(async (request) => {
const accessToken = AuthService.getAccessToken();
// injeta o token de acesso na requisição
if (accessToken) {
request.headers["Authorization"] = `Bearer ${accessToken}`;
}
return request;
});
// for multiple requests
let isRefreshing: boolean = false;
let failedQueue: any[] = [];
const processQueue = (error: any, token: string | null = null) => {
failedQueue.forEach((prom) => {
if (error) {
prom.reject(error);
} else {
prom.resolve(token);
}
});
failedQueue = [];
};
Service.setResponseInterceptors(
(response) => response,
async (error) => {
// recupera informações da requisição
const originalRequest = error.config;
// caso o erro seja de autenticação e ainda não foi feito o retry
if (error?.response?.status === 401 && !originalRequest._retry) {
if (isRefreshing) {
return new Promise(function (resolve, reject) {
failedQueue.push({ resolve, reject });
})
.then((token) => {
originalRequest.headers["Authorization"] = "Bearer " + token;
return axios(originalRequest);
})
.catch((err) => {
return Promise.reject(err);
});
}
originalRequest._retry = true;
isRefreshing = true;
// recupera o code verifier e o refresh token
const storage = {
codeVerifier: AuthService.getCodeVerifier(),
refreshToken: AuthService.getRefreshToken(),
};
const { codeVerifier, refreshToken } = storage;
// caso algum não exista, não é possível renovar o token
if (!refreshToken || !codeVerifier) {
AuthService.imperativelySendToLogout();
return;
}
try {
// renova o token
const tokens = await AuthService.getNewToken({
codeVerifier,
refreshToken,
});
// armazena os tokens para novas requisições
AuthService.setAccessToken(tokens.access_token);
AuthService.setRefreshToken(tokens.refresh_token);
// implementa o token na requisição
originalRequest.headers[
"Authorization"
] = `Bearer ${tokens.access_token}`;
processQueue(null, tokens.access_token);
// retorna uma nova chamada do axios com essa requisição
return axios(originalRequest);
} catch (err) {
processQueue(err, null);
throw err;
} finally {
isRefreshing = false;
}
}
throw error;
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment