Ожидаемое:
- Отправить http -запрос < /li>
Если ответ составляет 401 (токен истекло), мы получаем новый свежий токен и все запросы с новым запросом с новым токен. - Если ответ составляет 200, продолжайте
[*] Отправить http -запрос < /li>
Получить 10 Ответ 401 (9 Ответ на 10:15:10 и с 1 до 10:15:11) ( 1 секунда)
Получите свежий токен и ремейк 9 Запрос < /li>
Получить свежий токен снова и переделать другой запрос < /li>
< /ul>
Почему последний запрос не использует такой же токен? Как я могу сделать, чтобы снова не создавать новый токен, если старое действительное) < /p>
let isTokenRefreshing = false;
let subscribers = [];
let refreshTokenPromise = null; // Nous allons utiliser cette variable pour partager la promesse de rafraîchissement du token entre toutes les requêtes.
function onTokenRefreshed(token) {
console.log("Token refreshed:", token);
// Relance toutes les requêtes qui attendaient le token
subscribers.forEach(callback => callback(token));
subscribers = []; // Vide la file d'attente
}
function subscribeToTokenRefresh(callback) {
console.log("Nouvelle requête ajoutée à la file d'attente.");
subscribers.push(callback); // Ajoute les callbacks dans la file d'attente
}
window.axios.interceptors.response.use(
response => response, // Si la réponse est OK, on la retourne
async error => {
const originalRequest = error.config;
// Vérifie si c'est bien une erreur 401 et que la requête n'a pas déjà été retentée
if (error.response && error.response.status === 401 && !originalRequest._retry) {
console.log("401 détectée, tentative de rafraîchissement du token.");
// Si le token est déjà en cours de récupération, on attend
if (refreshTokenPromise) {
console.log("Le rafraîchissement du token est déjà en cours, on attend...");
return new Promise((resolve, reject) => {
subscribeToTokenRefresh(token => {
originalRequest.headers['Authorization'] = `Bearer ${token}`; // Mets à jour l'en-tête pour cette requête
resolve(axios(originalRequest)); // Relance la requête d'origine avec le nouveau token
});
});
}
console.log("Détails de la requête originale qui a échoué avec 401 :");
console.log("URL de la requête:", originalRequest.url);
console.log("Méthode de la requête:", originalRequest.method);
console.log("Headers de la requête:", originalRequest.headers);
// Marque cette requête comme étant en cours de réessai
originalRequest._retry = true;
console.log("Démarrage du rafraîchissement du token...");
// Si ce n'est pas encore fait, on initialise la promesse de rafraîchissement du token
refreshTokenPromise = axios.post('/api/refresh-token') // Remplacez cette URL par votre API de rafraîchissement de token
.then(response => {
const newToken = response.data.token;
console.log("Nouveau token récupéré :", newToken);
// Sauvegarde du nouveau token (par exemple, dans localStorage, Vuex, etc.)
localStorage.setItem('UserToken', newToken);
const user = {
isLoggedIn: true,
user: response.data.user
};
localStorage.setItem('User', JSON.stringify(user));
// On relance toutes les requêtes qui attendaient
onTokenRefreshed(newToken);
// Retourne le nouveau token
return newToken;
})
.catch(err => {
console.error("Erreur lors du rafraîchissement du token :", err);
return Promise.reject(err);
})
.finally(() => {
// Réinitialise la promesse de rafraîchissement du token
refreshTokenPromise = null;
});
// Maintenant on attend que la promesse de rafraîchissement se termine
const newToken = await refreshTokenPromise;
// Relance la requête initiale avec le nouveau token
originalRequest.headers['Authorization'] = `Bearer ${newToken}`;
return axios(originalRequest);
}
return Promise.reject(error); // Autres erreurs, on les passe
}
);
Подробнее здесь: https://stackoverflow.com/questions/794 ... terceptors
Мобильная версия