하관우 하관우 05-30
2025-05-30 하관우 alret 수정
@d2c76cc0feb4f34621bf50ce79ac3ed4bd59ba64
client/resources/api/index.js
--- client/resources/api/index.js
+++ client/resources/api/index.js
@@ -82,96 +82,114 @@
         }
     });
 
-    // 요청 인터셉터
-    client.interceptors.request.use(
-        async config => {
-            // 요청 전에 토큰 만료 확인 및 필요시 갱신
-            try {
-                await ensureValidToken();
-                const token = store.state.authorization;
-                if (token) {
-                    config.headers.Authorization = token;
+    // 요청 인터셉터 등록
+    if (client.interceptors.request.handlers.length === 0) {
+        client.interceptors.request.use(
+            async config => {
+                if (store.state.isHandlingSessionError) {
+                    return Promise.reject(new axios.Cancel('Error handling in progress'));
                 }
-            } catch (error) {
-                // 토큰 갱신 실패 시 로그인 페이지로 이동
-                if (!window.location.pathname.includes('/login')) {
-                    const redirect = window.location.pathname + window.location.search;
-                    sessionStorage.setItem("redirect", redirect);
-                    alert('세션이 종료되었습니다.\n로그인을 새로 해주세요.');
-                    store.commit("setStoreReset");
-                    window.location = '/login.page';
+                try {
+                    await ensureValidToken();
+                    const token = store.state.authorization;
+                    if (token) {
+                        config.headers.Authorization = token;
+                    }
+                } catch (error) {
+                    if (!store.state.isHandlingSessionError && !window.location.pathname.includes('/login')) {
+                        store.commit('setHandlingSessionError', true);
+                        const redirect = window.location.pathname + window.location.search;
+                        sessionStorage.setItem("redirect", redirect);
+                        alert('세션이 종료되었습니다.\n로그인을 새로 해주세요.');
+                        store.commit("setStoreReset");
+                        window.location = '/login.page';
+                    }
+                    return Promise.reject(error);
                 }
-                throw error;
-            }
-            return config;
-        },
-        error => {
-            return Promise.reject(error);
-        }
-    );
+                return config;
+            },
+            error => Promise.reject(error)
+        );
+    }
 
-    // 응답 인터셉터
-    client.interceptors.response.use(
-        response => {
-            return response;
-        },
-        async error => {
-            const originalReq = error.config;
+    // 응답 인터셉터 등록
+    if (client.interceptors.response.handlers.length === 0) {
+        client.interceptors.response.use(
+            response => response,
+            async error => {
+                if (store.state.isHandlingSessionError) {
+                    return Promise.reject(error);
+                }
 
-            // 403 에러 처리
-            if (error.response && error.response.status === 403) {
-                alert('접근 권한이 없습니다.');
-                window.history.back();
+                const originalReq = error.config;
+
+                if (error.response && error.response.status === 403) {
+                    if (!store.state.isHandlingSessionError) {
+                        store.commit('setHandlingSessionError', true);
+                        alert('접근 권한이 없습니다.');
+                        window.history.back();
+                    }
+                    return Promise.reject(error);
+                }
+
+                if (
+                    error.response &&
+                    error.response.status === 401 &&
+                    error.response.data.message === '로그인 시간이 만료되었습니다.' &&
+                    !originalReq._retry
+                ) {
+                    if (!store.state.isHandlingSessionError) {
+                        store.commit('setHandlingSessionError', true);
+                        originalReq._retry = true;
+
+                        try {
+                            await refreshToken();
+                            originalReq.headers.Authorization = store.state.authorization;
+
+                            if (
+                                originalReq.headers['Content-Type'] &&
+                                originalReq.headers['Content-Type'].includes('multipart/form-data')
+                            ) {
+                                return axios({
+                                    ...originalReq,
+                                    headers: {
+                                        ...originalReq.headers,
+                                        Authorization: store.state.authorization,
+                                    },
+                                    transformRequest: [(data) => data],
+                                });
+                            }
+                        } catch (refreshError) {
+                            const redirect = window.location.pathname + window.location.search;
+                            sessionStorage.setItem('redirect', redirect);
+                            alert('세션이 종료되었습니다.\n로그인을 새로 해주세요.');
+                            store.commit('setStoreReset');
+                            window.location = '/login.page';
+                            return Promise.reject(refreshError);
+                        }
+                    }
+                    return Promise.reject(error);
+                }
+
+                if (
+                    error.response &&
+                    (error.response.status === 400 || error.response.status === 500)
+                ) {
+                    if (!store.state.isHandlingSessionError) {
+                        store.commit('setHandlingSessionError', true);
+                        const redirect = window.location.pathname + window.location.search;
+                        sessionStorage.setItem('redirect', redirect);
+                        alert('세션이 종료되었습니다.\n로그인을 새로 해주세요.');
+                        store.commit('setStoreReset');
+                        window.location = '/login.page';
+                    }
+                    return Promise.reject(error);
+                }
+
                 return Promise.reject(error);
             }
-
-            // 401 에러 처리 (토큰 만료)
-            if (error.response &&
-                error.response.status === 401 &&
-                error.response.data.message === '로그인 시간이 만료되었습니다.' &&
-                !originalReq._retry) {
-
-                originalReq._retry = true; // 재시도 플래그 설정
-
-                try {
-                    // 토큰 재발급
-                    await refreshToken();
-
-                    // 새 토큰으로 헤더 업데이트
-                    originalReq.headers.Authorization = store.state.authorization;
-
-                    // multipart/form-data 요청 처리를 위한 특별 처리
-                    if (originalReq.headers['Content-Type'] &&
-                        originalReq.headers['Content-Type'].includes('multipart/form-data')) {
-
-                        // 완전히 새로운 요청 생성
-                        return axios({
-                            ...originalReq,
-                            headers: {
-                                ...originalReq.headers,
-                                Authorization: store.state.authorization
-                            },
-                            // FormData가 변경되지 않도록 원본 데이터 유지
-                            transformRequest: [(data) => data]
-                        });
-                    }
-
-                    // 일반 요청은 기존 client 사용하여 재시도
-                    return client(originalReq);
-                } catch (refreshError) {
-                    const redirect = window.location.pathname + window.location.search;
-                    sessionStorage.setItem("redirect", redirect);
-                    alert('세션이 종료되었습니다.\n로그인을 새로 해주세요.');
-                    store.commit("setStoreReset");
-                    window.location = '/login.page'; // 로그인 페이지로 리다이렉트
-                    return Promise.reject(refreshError);
-                }
-            }
-
-            return Promise.reject(error);
-        }
-    );
-
+        );
+    }
     return client;
 };
 
client/views/App.vue
--- client/views/App.vue
+++ client/views/App.vue
@@ -69,7 +69,6 @@
           this.$router.push('/login.page');
         }
       } catch (error) {
-        alert('세션이 종료되었습니다.\n로그인을 새로 해주세요.');
         this.store.commit("setStoreReset");
         this.$router.push('/login.page'); // 로그인 페이지로 리다이렉트
       }
client/views/pages/AppRouter.js
--- client/views/pages/AppRouter.js
+++ client/views/pages/AppRouter.js
@@ -136,10 +136,14 @@
 
   // 로그인 여부
   const isLoggedIn = !!store.state.authorization && !!store.state.userId;
+  const isHandlingSession = store.state.isHandlingSessionError;
   // 로그인이 필요한데 로그인이 안되어 있는 경우
-  if (requiresAuth && !isLoggedIn) {
+  if (requiresAuth && !isLoggedIn && !isHandlingSession) { // 요기! 플래그 조건 추가
     alert('로그인이 필요합니다.');
     return next('/Login.page');
+  } else if (requiresAuth && !isLoggedIn && isHandlingSession) {
+    // 세션 에러 처리 중이면 그냥 로그인 페이지로 이동
+    return next('/Login.page'); // 알림 없이 바로 리다이렉트
   }
 
   // 이미 로그인했는데 로그인 페이지로 가려는 경우
client/views/pages/AppStore.js
--- client/views/pages/AppStore.js
+++ client/views/pages/AppStore.js
@@ -10,6 +10,7 @@
     loginId: null, // 로그인 ID 추가
     userNm: null, // 사용자 이름 추가
     roles: [], // 사용자 권한
+    isHandlingSessionError: false,
   },
   getters: {
     getAuthorization(state) {
@@ -38,12 +39,16 @@
     setRoles(state, newValue) {
       state.roles = newValue; // 사용자 권한 설정
     },
+    setHandlingSessionError(state, newValue) {
+      state.isHandlingSessionError = newValue; // 요기! 플래그 변경 뮤테이션
+    },
     setStoreReset(state) {
       state.authorization = null;
       state.userNm = null;
       state.userId = null;
       state.roles = [];
       state.loginId = null;
+      state.isHandlingSessionError = false;
     },
   },
   actions: {
client/views/pages/bbsDcryPhoto/PicHistoryDetail.vue
--- client/views/pages/bbsDcryPhoto/PicHistoryDetail.vue
+++ client/views/pages/bbsDcryPhoto/PicHistoryDetail.vue
@@ -155,10 +155,14 @@
 
         this.isRegister = this.$registerChk(this.findResult.register);
       } catch (error) {
+        if (this.$store.state.isHandlingSessionError) {
+          console.log("세션 에러 처리 중이라 조회 오류 알림 무시.");
+          return; // 세션 에러 처리 중이면 여기서 멈춤
+        }
         alert('조회중 오류가 발생했습니다.');
         this.fnMoveTo('list');
 
-        if (error.response) {
+        if (error.response && error.response.data && error.response.data.message) {
           alert(error.response.data.message);
         }
         console.error(error.message);
client/views/pages/bbsDcryVideo/VideoHistoryDetail.vue
--- client/views/pages/bbsDcryVideo/VideoHistoryDetail.vue
+++ client/views/pages/bbsDcryVideo/VideoHistoryDetail.vue
@@ -124,10 +124,14 @@
         }
         this.isRegister = this.$registerChk(this.findResult.register);
       } catch (error) {
+        if (this.$store.state.isHandlingSessionError) {
+          console.log("세션 에러 처리 중이라 조회 오류 알림 무시.");
+          return; // 세션 에러 처리 중이면 여기서 멈춤
+        }
         alert('조회중 오류가 발생했습니다.');
         this.fnMoveTo('list');
 
-        if (error.response) {
+        if (error.response && error.response.data && error.response.data.message) {
           alert(error.response.data.message);
         }
         console.error(error.message);
client/views/pages/bbsMediaVido/MediaVideoDetail.vue
--- client/views/pages/bbsMediaVido/MediaVideoDetail.vue
+++ client/views/pages/bbsMediaVido/MediaVideoDetail.vue
@@ -116,10 +116,14 @@
         this.findResult = response.data.data.mediaVido;
         this.isRegister = this.$registerChk(this.findResult.register);
       } catch (error) {
+        if (this.$store.state.isHandlingSessionError) {
+          console.log("세션 에러 처리 중이라 조회 오류 알림 무시.");
+          return; // 세션 에러 처리 중이면 여기서 멈춤
+        }
         alert('조회중 오류가 발생했습니다.');
         this.fnMoveTo('list');
 
-        if (error.response) {
+        if (error.response && error.response.data && error.response.data.message) {
           alert(error.response.data.message);
         }
         console.error(error.message);
client/views/pages/bbsNesDta/NewsReleaseDetail.vue
--- client/views/pages/bbsNesDta/NewsReleaseDetail.vue
+++ client/views/pages/bbsNesDta/NewsReleaseDetail.vue
@@ -120,9 +120,13 @@
         this.findResult = response.data.data.nesDta;
         this.isRegister = this.$registerChk(this.findResult.register);
       } catch (error) {
+        if (this.$store.state.isHandlingSessionError) {
+          console.log("세션 에러 처리 중이라 조회 오류 알림 무시.");
+          return; // 세션 에러 처리 중이면 여기서 멈춤
+        }
         alert('조회중 오류가 발생했습니다.');
 
-        if (error.response) {
+        if (error.response && error.response.data && error.response.data.message) {
           alert(error.response.data.message);
         }
         console.error(error.message);
Add a comment
List