Skip to content

Conversation

@10tacion
Copy link
Member

@10tacion 10tacion commented Jul 26, 2025

[ Feat ] 로그인 상태 유지할 수 있도록 코드 수정

🔥 Related Issues

+++ 07.26.21.05 내일까지 자세하게 이슈 정리해서 pr 내용 추가하겠습니다. 조금만 기다려주십셔 🙇‍♂️🙇‍♂️🙇‍♂️

  • 정리 완

✅ 작업 리스트

  • 브라우저와 Electron 빌드 환경 분리 및 플래그 추가
  • 로그인 페이지에서 토큰 존재 시 자동 홈 리다이렉트 기능 구현
  • ProtectedRoute 네비게이션 로직 개선 (<Navigate>useNavigate)
  • 인증 상태 관리 중앙집중화 (auth config 도입)
  • 로그아웃 훅 분리 및 토큰 관리 로직 개선
  • Electron 메인 프로세스 모듈 구조 분리
  • 온보딩 완료 상태 localStorage 저장/복원 기능
  • 리다이렉트 페이지 코드스플릿팅 제외 (동기화 이슈 해결)
  • 새로운 로티 애니메이션 파일 적용

🔧 작업 내용

1. 브라우저/ 파일 시스템에서의 public path(vite.config.ts의 base) 분기

📁 변경 파일: package.json, vite.config.ts

  • --mode react 플래그 추가로 브라우저, 일렉트론 환경에서 vite.config.ts의 base를 다르게 적용해줌으로써 public path(루트 경로 Prefix)를 다르게 설정해주었습니다.
  • vite.config.ts에서 base에 따른 브라우저, 일렉트론 경로 인식의 차이는 다음과 같아요.
    • base: / (절대 경로)
      • 브라우저: 최상위 도메인(https://app.morib.in) -> 최상위 도메인은 보통 dist 폴더를 가리키고 있음. 적절
      • 일렉트론: 파일시스템 최상위(file://) 부적절 - file://electron.js
    • base: ./ (상대 경로)
      • 브라우저: 현재 도메인(https://app.morib.in/example) 부적절 - https://app.morib.in/example
      • 일렉트론: 패키징된 앱이 loadFile로 불러오는 html이 위치한 폴더 적절
  • base를 기준으로 js 번들을 포함한 리소스를 불러오기 때문에, 브라우저는 절대경로, 일렉트론은 상대경로가 적절합니다.
// package.json 주요 변경사항
{
  "dev:react": "vite --mode react",
  "build": "tsc -b && vite build --mode react", 
  "build:electron": "tsc -b && vite build"
}

//vite.config.ts

export default defineConfig(({ mode }) => {
	const isReact = mode === 'react';

	return {
...
		base: isReact ? '/' : './',
...
});

2. 인증 상태 관리 중앙집중화

📁 새 파일: src/app/shared/config/auth.ts
📁 변경 파일: src/app/shared/utils/auth.ts

// 새로 추가된 auth config
export const authConfig = {
  google: {
    url: {
      react: import.meta.env.VITE_GOOGLE_URL,
      electron: import.meta.env.VITE_ELECTRON_AUTH_URL,
    },
  },
  isAuthenticated: () => !!getAccessToken(),
  isOnboardingCompleted: () => !!getIsOnboardingCompleted(),
  redirectToLogin: () => redirect(ROUTES_CONFIG.login.path),
};

// auth.ts에 추가된 함수들
export const getIsOnboardingCompleted = () => localStorage.getItem('isOnboardingCompleted');
export const setIsOnboardingCompleted = (value: string) => localStorage.setItem('isOnboardingCompleted', value);
export const removeAllTokens = () => {
  localStorage.removeItem('accessToken');
  localStorage.removeItem('refreshToken'); 
  localStorage.removeItem('isOnboardingCompleted');
};

3. 로그인 페이지에서 이미 토큰이 존재할 경우 home으로 리디렉션

📁 변경 파일: src/app/pages/LoginPage/LoginPage.tsx

  • 컴포넌트 마운트 시 토큰 존재 여부 확인
  • 이미 인증된 사용자 자동 홈 리다이렉트
  • 새로운 메인 로티 애니메이션 파일 적용
// 추가된 자동 리다이렉트 로직
useEffect(() => {
  if (authConfig.isAuthenticated()) {
    navigate(ROUTES_CONFIG.home.path);
  }
}, [navigate]);

4. 라우팅 로직 개선

📁 변경 파일: src/app/router/ProtectedRoute.tsx, src/app/router/Router.tsx

  • Navigate를 사용했을 때 왜 오작동하고, useNavigate를 사용했을 때 제대로 동작하는지 원인 파악을 못했어요.. 다시 잘 파악해보겠습니다.
  • <Navigate> 컴포넌트에서 useNavigate 훅으로 변경하여 이슈 해결

5. Electron 메인 프로세스에서 URL 로딩 시 "A component suspended while responding to synchronous input" 오류 해결

  • 메인 프로세스에서 토큰을 주입 받은 후 redirect 페이지로 리다이렉션 하는데 위 오류가 발생했어요
  • 위 오류가 발생하는 원인은 동기입력 도중(앱이 딥링크 신호를 처리) lazy loading을 통해서 분리된 번들을 동기적으로 불러올 때 suspense를 통해서 대체할 fallback을 설정해주지 않아서 발생하는 오류였어요.
  • 단순히 suspense를 통해서 감싸주어도 되지만 redirect 페이지 번들의 크기는 작기 때문에 메인 번들에 포함되어도 무리가 없다고 판단해 메인 번들에 포함시켰습니다.
  • 레이지 로딩을 하면 초기 로딩속도에 이득이 있지만, 결국 다른 페이지로 라우팅 할 때 로드되는 시간이 증가해요. 리다이렉트 페이지는 번들 사이즈가 작기 때문에 초기 로딩속도에 미치는 영향이 미미해요. 그래서 이를 메인 번들에 포함시켜, 리다이렉트 페이지를 로드할 때 걸리는 delay를 줄여주는 것에 더 이점이 있다고 생각했어요.

6. 로그아웃 기능 개선

📁 새 파일: src/app/shared/hooks/useLogout.ts
📁 변경 파일: src/app/shared/apisV2/setting/setting.mutations.ts, AccountContent.tsx

  • 로그아웃 로직을 커스텀 훅으로 분리
  • 일렉트론에서는 각 컴퓨터별 경로를 정확히 알수 없기 때문에 window.location.href 사용이 어려워요. 그래서 간단하게 React Router 네비게이션을 활용했습니다.
  • location.href 대신 React Router 네비게이션 활용 (일렉트론의 파일 시스템 경로 고려)
  • 모든 토큰 정리 로직 통합

7. Electron 메인 프로세스 역할 별로 모듈 분리

📁 변경 파일: src/electron/main.ts (94줄 추가, 252줄 삭제)
📁 새 파일들:

  • src/electron/contants/protocol.ts - 프로토콜 상수
  • src/electron/monitor/browser.ts - 브라우저 모니터링 로직
  • src/electron/notification/mac.ts - macOS 알림 기능
  • src/electron/window/key.ts - 키보드 제어 로직
  • src/electron/window/os.ts - OS 관련 유틸리티
  • src/electron/window/resolution.ts - 해상도/줌 관리

주요 개선사항:

  • 기존: authWindowmainWindow 두 개 창 관리 → 변경: mainWindow 하나로 통합
  • 나누어져 있던 Window(렌더러 프로세스)를 통합했습니다.
  • 크로니움은 URL의 origin을 기반으로 로컬스토리지를 공유하기 때문에 렌더러 프로세스를 하나로 통일하여 종료했다가 재실행해도 토큰이 남아 있을 수 있도록 했습니다.
  • 기능별 모듈 분리로 코드 가독성 및 유지보수성 향상
  • 상세한 주석 추가로 코드 이해도 증대

🧐 새로 알게된 점

  1. <Navigate> 컴포넌트와 useNavigate 훅의 동작 차이

    • <Navigate>는 렌더링 시점에 즉시 리다이렉트
    • useNavigate는 이벤트 핸들러 내에서 호출 시 더 안정적이다.
  2. Electron vs Browser 경로 인식:

    • 브라우저: 상대경로로 리소스 인식
    • Electron: 파일 시스템 내 절대경로로 인식
    • Vite 빌드 모드로 환경별 최적화 가능
  3. 코드스플릿팅과 Suspense:

    • Electron 메인 프로세스에서 URL 로딩 시 "A component suspended while responding to synchronous input" 오류 발생
    • lazy 함수를 적용했다면 꼭 suspense를 체크하자.
  4. Electron 모듈 분리의 효과:

    • 단일 파일 346줄 → 여러 모듈로 분리하여 94줄로 축소
    • 기능별 분리로 테스트 가능성 및 재사용성 향상

🤔 궁금한 점

📸 스크린샷 / GIF / Link

10tacion added 8 commits July 26, 2025 20:51
- 브라우저의 경우 상대경로로 경로 인식, 일렉트론의 경우 파일 시스템 내에서 절대경로로 경로 인식하기 때문
- 메인 프로세스에서 url을 로딩했을 때,  A component suspended while responding to synchronous input. 이슈로 임시로 제외해두었음
- <Navigate>와 useNavigation 동작의 차이로 인해서 수정
- 파일 시스템에서 경로 파악에 어려움이있어 location.href 대신 리액트 라우터의 네비게이션 활용
@10tacion 10tacion self-assigned this Jul 27, 2025
@10tacion 10tacion merged commit c5bd136 into develop Aug 2, 2025
1 check passed
@10tacion 10tacion deleted the feat/#326/keep-login-session branch August 2, 2025 00:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ Feat ] 로그인 상태 유지할 수 있도록 일렉트론 로직 수정

2 participants