hmkim 06-09
250609 김혜민 로그아웃 세션 및 토큰제거 수정
@b232a0ec1f8ad6b8703e32056b53473f957a392a
client/views/index.js
--- client/views/index.js
+++ client/views/index.js
@@ -25,9 +25,6 @@
   const ctx = await contextPath();
   const strgMode = await storageMode();
   const lgnMode = await loginMode();
-  console.log("Context Path:", ctx);
-  console.log("Storage Mode:", strgMode);
-  console.log("Login Mode:", lgnMode);
 
   const store = createAppStore(ctx, strgMode, lgnMode);
 
client/views/pages/AppStore.js
--- client/views/pages/AppStore.js
+++ client/views/pages/AppStore.js
@@ -123,81 +123,218 @@
       },
     },
     actions: {
-      async logout({ commit }) {
+      async logout({ commit, state, dispatch }) {
+        console.log('로그아웃 프로세스 시작');
+        
+        const ctx = state.contextPath;
+        const admPath = state.path?.includes("/adm");
+        const loginMode = state.loginMode || localStorage.getItem('loginMode') || 'J';
+        
         try {
-          const ctx = this.state.contextPath;
-          const admPath = this.state.path?.includes("/adm")
-          const loginMode = this.state.loginMode || localStorage.getItem('loginMode') || 'J'; 
-          
-          // 로그인 모드에 따른 처리
-          if (loginMode === 'J') {
-            // JWT 방식인 경우만 서버 API 호출
-            try {
-              const res = await logOutProc();
-              if (res.data.message) {
-                alert(res.data.message);
-              }
-            } catch (error) {
-              console.log(error);
-              // API 에러가 발생해도 클라이언트는 정리
+          // 1. 서버 로그아웃 API 호출 (모든 모드에서 호출)
+          try {
+            const res = await logOutProc();
+            console.log('서버 로그아웃 응답:', res);
+            
+            if (res?.data?.message) {
+              console.log('로그아웃 메시지:', res.data.message);
             }
+          } catch (apiError) {
+            // API 호출 실패해도 클라이언트 정리는 계속 진행
+            console.warn('서버 로그아웃 API 호출 실패:', apiError.message);
           }
+          
+          // 2. 클라이언트 완전 정리
+          await dispatch('performCompleteCleanup', { loginMode, ctx, admPath });
+          
+        } catch (error) {
+          console.error("로그아웃 처리 중 오류:", error);
+          
+          // 오류 발생해도 클라이언트 정리는 수행
+          await dispatch('performCompleteCleanup', { loginMode, ctx, admPath });
+          
+          // 사용자에게는 간단한 메시지만 표시
+          console.log("로그아웃 처리가 완료되었습니다.");
+        }
+      },
+      
+      // 완전한 클라이언트 정리 수행
+      async performCompleteCleanup({ commit, dispatch }, { loginMode, ctx, admPath }) {
+        try {
+          console.log('클라이언트 정리 시작');
           
           // 1. 상태 초기화
           commit("setStoreReset");
           
-          // 2. 로컬스토리지와 세션스토리지 초기화
-          localStorage.clear();
-          sessionStorage.clear();
-
-          // 3. 모든 가능한 쿠키 삭제 (OAuth 관련 포함)
-          const cookiesToDelete = [
-            'refresh', 
-            'Authorization', 
-            'JSESSIONID', 
-            'oauth_access_token',
-            'oauth_refresh_token',
-            'SESSION'
-          ];
+          // 2. 모든 저장소 완전 정리
+          dispatch('clearAllStorages');
           
-          cookiesToDelete.forEach(cookieName => {
-            document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
-            document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=${window.location.hostname};`;
-          });
+          // 3. 모든 쿠키 제거
+          dispatch('clearAllCookies');
           
-          // 4. 로그인 페이지로 이동
-          const cleanUrl = admPath ? 
-            ctx + "/cmslogin.page" : 
-            ctx + "/login.page";
-            
-          window.history.replaceState({}, document.title, cleanUrl);
-          window.location.href = cleanUrl;
-          
-        } catch(error) {
-          console.error("로그아웃 처리 중 오류:", error);
-          
-          // 에러가 발생해도 클라이언트 상태는 정리
-          commit("setStoreReset");
-          localStorage.clear();
-          sessionStorage.clear();
-          
-          const ctx = this.state.contextPath;
-          const admPath = this.state.path?.includes("/adm");
-          
-          const errorData = error.response?.data;
-          if (errorData?.message) {
-            alert(errorData.message);
-          } else {
-            console.log("로그아웃 처리 중 예상치 못한 오류 발생");
+          // 4. 세션 무효화 (세션 모드인 경우)
+          if (loginMode === 'S') {
+            dispatch('invalidateSession');
           }
           
-          const cleanUrl = admPath ? 
-            ctx + "/cmslogin.page" : 
-            ctx + "/login.page";
+          // 5. 브라우저 캐시 정리
+          dispatch('clearBrowserCache');
+          
+          // 6. 페이지 리다이렉트
+          const loginUrl = admPath ? 
+            (ctx || '') + "/cmslogin.page" : 
+            (ctx || '') + "/login.page";
             
-          window.location.href = cleanUrl;
+          console.log('로그인 페이지로 이동:', loginUrl);
+          
+          // 히스토리 정리 후 이동
+          window.history.replaceState(null, '', loginUrl);
+          window.location.href = loginUrl;
+          
+        } catch (cleanupError) {
+          console.error('클라이언트 정리 중 오류:', cleanupError);
+          
+          // 최종 수단: 강제 새로고침
+          window.location.reload();
         }
       },
+      
+      // 모든 저장소 정리
+      clearAllStorages() {
+        try {
+          // localStorage 완전 정리
+          const localStorageKeys = Object.keys(localStorage);
+          localStorageKeys.forEach(key => {
+            localStorage.removeItem(key);
+          });
+          localStorage.clear();
+          
+          // sessionStorage 완전 정리
+          const sessionStorageKeys = Object.keys(sessionStorage);
+          sessionStorageKeys.forEach(key => {
+            sessionStorage.removeItem(key);
+          });
+          sessionStorage.clear();
+          
+          console.log('모든 저장소 정리 완료');
+        } catch (error) {
+          console.error('저장소 정리 중 오류:', error);
+        }
+      },
+      
+      // 모든 쿠키 제거
+      clearAllCookies() {
+        try {
+          const cookiesToDelete = [
+            // 일반 인증 쿠키
+            'refresh', 
+            'Authorization', 
+            'access_token',
+            'JSESSIONID', 
+            'SESSION',
+            
+            // OAuth 관련 쿠키
+            'oauth_access_token',
+            'oauth_refresh_token',
+            'oauth_state',
+            'OAUTH2_AUTHORIZATION_REQUEST',
+            'oauth2_auth_request',
+            
+            // 카카오 관련
+            'kakao_login',
+            '_kadu',
+            '_kadub',
+            '_kalt',
+            
+            // 네이버 관련
+            'NID_AUT',
+            'NID_SES',
+            'NID_JKL',
+            
+            // 구글 관련
+            'SACSID',
+            'APISID',
+            'SSID',
+            '1P_JAR',
+            
+            // 기타 가능한 쿠키
+            'remember-me',
+            'user-session',
+            'auth-token'
+          ];
+          
+          const domains = [
+            '', 
+            '.' + window.location.hostname,
+            window.location.hostname,
+            '.localhost',
+            'localhost'
+          ];
+          
+          const paths = ['/', '/oauth2', '/login', '/auth'];
+          
+          cookiesToDelete.forEach(cookieName => {
+            paths.forEach(path => {
+              domains.forEach(domain => {
+                // 기본 쿠키 삭제
+                document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path};`;
+                
+                // 도메인별 쿠키 삭제
+                if (domain) {
+                  document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}; domain=${domain};`;
+                }
+              });
+            });
+          });
+          
+          console.log('모든 쿠키 제거 완료');
+        } catch (error) {
+          console.error('쿠키 제거 중 오류:', error);
+        }
+      },
+      
+      // 세션 무효화
+      invalidateSession() {
+        try {
+          // 세션 무효화를 위한 더미 요청 (필요한 경우)
+          fetch('/mbr/sessionInvalidate', {
+            method: 'POST',
+            credentials: 'include'
+          }).catch(() => {}); // 실패해도 무시
+          
+        } catch (error) {
+          console.error('세션 무효화 중 오류:', error);
+        }
+      },
+      
+      // 브라우저 캐시 정리
+      clearBrowserCache() {
+        try {
+          // 캐시 API 지원 확인 및 정리
+          if ('caches' in window) {
+            caches.keys().then(cacheNames => {
+              cacheNames.forEach(cacheName => {
+                caches.delete(cacheName);
+              });
+            }).catch(() => {});
+          }
+          
+          // IndexedDB 정리 (가능한 경우)
+          if ('indexedDB' in window) {
+            // 일반적인 DB 이름들 정리 시도
+            const commonDBNames = ['auth_db', 'user_db', 'session_db'];
+            commonDBNames.forEach(dbName => {
+              try {
+                indexedDB.deleteDatabase(dbName);
+              } catch (e) {}
+            });
+          }
+          
+        } catch (error) {
+          console.error('브라우저 캐시 정리 중 오류:', error);
+        }
+      },
+
       setUserType({ commit }, userType) {
         commit("setUserType", userType);
       },
client/views/pages/login/Login.vue
--- client/views/pages/login/Login.vue
+++ client/views/pages/login/Login.vue
@@ -155,9 +155,7 @@
     },
 
     async loginSuccessProc(res) {
-      console.log('login success :: res? = ' , res);
       const loginType = res.headers['loginmode'];
-      console.log('loginType  :  ', loginType);
       if (loginType === 'J') {
         this.handleJWTLogin(res);
       } else if (loginType === 'S') {
@@ -269,7 +267,6 @@
         await this.handleLoginSuccess();
 
       } catch (error) {
-        console.error("OAuth2 처리 실패:", error);
         this.handleOAuthError('processing_error', error.message);
       }
     },
@@ -287,8 +284,6 @@
     },
 
     async handleOAuthJWT() {
-      console.log("JWT 모드 OAuth2 처리 시작");
-      
       try {
         const token = localStorage.getItem('authorization') 
             || this.getCookie('refresh') 
@@ -344,7 +339,6 @@
         this.setAuthInfo('S', null, { ...userInfo, roles });
         
       } catch (error) {
-        console.error("세션 모드 처리 실패:", error);
         throw error;
       }
     },
Add a comment
List