فهرست منبع

fix: :bug: logica de retry depois de 401

Denis 1 سال پیش
والد
کامیت
cdd5a3ad76
3فایلهای تغییر یافته به همراه37 افزوده شده و 52 حذف شده
  1. 32 43
      src/boot/axios.js
  2. 4 8
      src/composables/useAuth.js
  3. 1 1
      src/stores/permission.js

+ 32 - 43
src/boot/axios.js

@@ -1,7 +1,7 @@
 import { boot } from "quasar/wrappers";
 import { useAuth } from "src/composables/useAuth";
 import { Cookies, Notify } from "quasar";
-import axios from "axios";
+import axios, { AxiosError } from "axios";
 // Be careful when using SSR for cross-request state pollution
 // due to creating a Singleton instance here;
 // If any client changes this (global) instance, it might be a
@@ -9,16 +9,6 @@ import axios from "axios";
 // "export default () => {}" function below (which runs individually
 // for each client)
 
-let isRefreshing = false;
-let failedQueue = [];
-
-const processQueue = (error, token = null) => {
-  failedQueue.forEach((prom) =>
-    error ? prom.reject(error) : prom.resolve(token),
-  );
-  failedQueue = [];
-};
-
 const api = axios.create({
   baseURL: process.env.API_URL + "/api",
   withCredentials: true,
@@ -40,40 +30,39 @@ api.interceptors.request.use(
   },
 );
 
-const errorInterceptor = async (error) => {
-  if (error.response.status === 401) {
-    if (!isRefreshing) {
-      isRefreshing = true;
-      const isRefreshValid = await useAuth().refreshToken();
-      isRefreshing = false;
-      if (!isRefreshValid) {
-        Cookies.remove("access_token");
-        Cookies.remove("refresh_token");
-        window.location.href = "/login";
-        processQueue(new Error("Token refresh failed"), null);
-        return Promise.reject(new Error("Token refresh failed"));
-      } else {
-        processQueue(null, true);
-      }
-    }
-
-    return new Promise((resolve, reject) => {
-      failedQueue.push({ resolve, reject });
-    })
-      .then(() => {
-        return api.request(error.config);
-      })
-      .catch((err) => {
-        return Promise.reject(err);
+const errorInterceptor = (error) => {
+  return new Promise((resolve, reject) => {
+    if (error.response.status === 401) {
+      useAuth()
+        .refreshToken()
+        .then((response) => {
+          if (response instanceof AxiosError) {
+            Cookies.remove("access_token");
+            Cookies.remove("refresh_token");
+            window.location.href = "/login";
+            reject(response);
+          } else {
+            api
+              .request(error.config)
+              .then((res) => {
+                resolve(res);
+              })
+              .catch((apiError) => {
+                reject(apiError);
+              });
+          }
+        })
+        .catch((refreshError) => {
+          reject(refreshError);
+        });
+    } else {
+      Notify.create({
+        message: error.response.data.message,
+        type: "negative",
       });
-  }
-
-  Notify.create({
-    message: error.response.data.message,
-    type: "negative",
+      reject(error);
+    }
   });
-
-  return Promise.reject(error);
 };
 
 const successInterceptor = (response) => {

+ 4 - 8
src/composables/useAuth.js

@@ -1,12 +1,9 @@
 import { api } from "src/boot/axios";
 import { Cookies } from "quasar";
-import { useRouter } from "vue-router";
 import { permissionStore } from "src/stores/permission";
 import { userStore } from "src/stores/user";
 
 export const useAuth = () => {
-  const router = useRouter();
-
   const login = async (email, password) => {
     try {
       const response = await api.post("/login", {
@@ -31,8 +28,9 @@ export const useAuth = () => {
         userStore().user = payload.user;
         await permissionStore().fetchScopes();
       }
+      return response;
     } catch (error) {
-      console.error(error);
+      return error;
     }
   };
 
@@ -43,7 +41,6 @@ export const useAuth = () => {
         Cookies.remove("access_token");
         Cookies.remove("refresh_token");
         await permissionStore().fetchScopes();
-        router.push({ name: "Login" });
       }
     } catch (error) {
       console.error(error);
@@ -74,10 +71,9 @@ export const useAuth = () => {
         userStore().user = payload.user;
       }
 
-      return true;
+      return response;
     } catch (error) {
-      console.error(error);
-      return false;
+      return error;
     }
   };
 

+ 1 - 1
src/stores/permission.js

@@ -97,7 +97,7 @@ export const permissionStore = defineStore("permission", () => {
     try {
       const accessToken = Cookies.get("access_token");
       if (accessToken) {
-        userStore().fetchUser();
+        await userStore().fetchUser();
         const response = await getUserPermissions();
         permissions.value = response;
       } else {