Conversation
Walkthrough사이드바에 토큰 기반 로그아웃 동작과 로그인 상태 추적을 추가하고, 새 훅 Changes
Sequence Diagram(s)sequenceDiagram
participant User as 사용자
participant Sidebar as Sidebar 컴포넌트
participant Storage as localStorage
participant API as 인증 서버
participant Router as 라우터
User->>Sidebar: 로그아웃 클릭
Sidebar->>Storage: accessToken 읽기
Sidebar->>API: POST /logout (Authorization: Bearer <token>)
API-->>Sidebar: 응답 (성공/에러)
alt 응답 수신 (성공 또는 에러)
Sidebar->>Storage: accessToken, refreshToken 제거
Sidebar->>Sidebar: isLoggedIn = false
Sidebar->>Router: navigate("/")
Sidebar-->>User: toast로 로그아웃 알림
end
sequenceDiagram
participant User as 사용자
participant Page as Mypage / StockGame
participant Storage as localStorage
participant Router as 라우터
participant Login as /login 페이지
User->>Page: 페이지 접근
Page->>Storage: accessToken 확인 (useAuthGuard)
alt 토큰 없음
Page-->>User: toast.error(한국어) 표시
Page->>Router: navigate("/login")
Router->>Login: 리다이렉트
else 토큰 존재
Page->>Page: 정상 렌더링
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
시
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
frontend/src/pages/Mypage.jsx (1)
9-15: 동일한 문제: 의존성 누락 및 코드 중복.
StockGame.jsx와 동일한 문제가 있습니다:
useEffect의존성 배열에nav가 누락되었습니다.- 동일한 로그인 가드 로직이 반복됩니다.
StockGame.jsx에 제안한 것과 동일하게 커스텀 훅으로 추출하여 두 파일 모두에서 재사용하세요:const Mypage = () => { - const nav = useNavigate(); - useEffect(() => { - if (!localStorage.getItem('accessToken')) { - alert('로그인 후 이용하실 수 있습니다.'); - nav('/login'); - } - }, []); + useAuthGuard();
🧹 Nitpick comments (1)
frontend/src/components/Sidebar.jsx (1)
169-172:NavLink의to속성이 로그아웃 동작과 불일치.로그아웃 링크가
to="/"로 설정되어 있지만, 실제로는onClick핸들러에서navigate('/')를 호출합니다. 이는 약간 중복적이며, 사용자가 링크를 중간 클릭하거나 우클릭하여 새 탭에서 열 경우 로그아웃 없이 홈으로 이동할 수 있습니다.다음 diff를 적용하여 개선하세요:
<li> - <NavLink - to="/" - className={styles['inactive-link']} - onClick={logout} - > + <button + className={styles['inactive-link']} + onClick={logout} + style={{ background: 'none', border: 'none', cursor: 'pointer', textAlign: 'left', width: '100%' }} + > 로그아웃 - </NavLink> + </button> </li>또는 이벤트를 막으려면:
<NavLink to="/" className={styles['inactive-link']} - onClick={logout} + onClick={(e) => { + e.preventDefault(); + logout(); + }} > 로그아웃 </NavLink>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
frontend/src/components/Sidebar.jsx(3 hunks)frontend/src/pages/Mypage.jsx(1 hunks)frontend/src/pages/StockGame.jsx(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
frontend/src/pages/StockGame.jsx (2)
frontend/src/pages/Mypage.jsx (1)
nav(9-9)frontend/src/pages/Attendance.jsx (1)
nav(15-15)
frontend/src/pages/Mypage.jsx (2)
frontend/src/pages/StockGame.jsx (1)
nav(10-10)frontend/src/pages/Attendance.jsx (1)
nav(15-15)
🔇 Additional comments (4)
frontend/src/pages/StockGame.jsx (1)
4-5: 임포트 추가 확인.
useEffect와useNavigate임포트가 적절하게 추가되었습니다.frontend/src/pages/Mypage.jsx (1)
5-6: 임포트 추가 확인.
useEffect와useNavigate임포트가 적절하게 추가되었습니다.frontend/src/components/Sidebar.jsx (2)
4-4: API 임포트 확인.axios 유틸리티에서
api임포트가 적절하게 추가되었습니다.
153-206: 조건부 렌더링 구현 확인.로그인 상태에 따른 계정 메뉴의 조건부 렌더링이 적절하게 구현되었습니다. 로그인 시 마이페이지와 로그아웃, 비로그인 시 로그인과 회원가입 링크가 표시됩니다.
다만 Lines 27-29에서 언급한 상태 동기화 문제로 인해, 다른 탭에서 로그인/로그아웃 시 이 UI가 자동으로 업데이트되지 않을 수 있습니다.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
frontend/src/hooks/useAuthGuard.js (1)
7-12: 마운트 시점에만 인증 체크가 수행됩니다.현재 구현은 컴포넌트 마운트 시 한 번만 토큰을 확인합니다. 사용자가 페이지에 머무는 동안 토큰이 삭제되거나 만료되어도 리디렉션이 발생하지 않습니다.
현재 구현도 기본적인 route guard로 충분히 작동하지만, 더 강력한 보호가 필요하다면 다음을 고려하세요:
- 토큰 만료 시간 검증
- storage 이벤트 리스너로 다른 탭에서의 로그아웃 감지
- 주기적인 토큰 유효성 검증
선택적으로 다음과 같이 개선할 수 있습니다:
useEffect(() => { + const checkAuth = () => { + if (!localStorage.getItem('accessToken')) { + alert('로그인 후 이용하실 수 있습니다.'); + nav('/login'); + } + }; + + checkAuth(); + + // 다른 탭에서 로그아웃 시 감지 + window.addEventListener('storage', checkAuth); + return () => window.removeEventListener('storage', checkAuth); - if (!localStorage.getItem('accessToken')) { - alert('로그인 후 이용하실 수 있습니다.'); - nav('/login'); - } }, [nav]);frontend/src/components/Sidebar.jsx (1)
169-177: 로그아웃 링크에서 중복 네비게이션이 발생합니다.Line 171의
to="/"와 Line 173의onClick={logout}(내부에서navigate('/')호출)가 중복으로 홈으로 이동시킵니다.현재도 정상 작동하지만, 다음과 같이 개선하면 더 명확합니다:
방법 1: to 속성 제거
<li> <NavLink - to="/" + to="#" className={styles['inactive-link']} onClick={logout} > 로그아웃 </NavLink> </li>방법 2: preventDefault 사용
<li> <NavLink to="/" className={styles['inactive-link']} - onClick={logout} + onClick={(e) => { + e.preventDefault(); + logout(); + }} > 로그아웃 </NavLink> </li>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
frontend/src/components/Sidebar.jsx(3 hunks)frontend/src/hooks/useAuthGuard.js(1 hunks)frontend/src/pages/Mypage.jsx(1 hunks)frontend/src/pages/StockGame.jsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- frontend/src/pages/StockGame.jsx
- frontend/src/pages/Mypage.jsx
🔇 Additional comments (3)
frontend/src/hooks/useAuthGuard.js (1)
1-13: 전반적인 구조가 명확합니다.인증 가드 훅의 구현이 간결하고 목적에 부합합니다. 기본적인 클라이언트 사이드 라우트 보호 기능을 잘 수행합니다.
frontend/src/components/Sidebar.jsx (2)
27-29: Boolean 변환 개선 완료, 크로스탭 동기화는 여전히 누락.
!!localStorage.getItem('accessToken')로 변경하여 타입 일관성 문제가 해결되었습니다.다만 이전 리뷰에서 제안된 storage 이벤트 리스너를 통한 크로스탭 동기화는 아직 구현되지 않았습니다. 다른 탭에서 로그인/로그아웃 시 이 컴포넌트의 상태가 자동으로 업데이트되지 않습니다. 이미 제안된 사항이므로 우선순위에 따라 적용 여부를 결정하시면 됩니다.
154-207: 조건부 렌더링 로직이 명확하고 일관성 있습니다.인증 상태에 따른 계정 섹션 메뉴 항목 표시가 깔끔하게 구현되었습니다. NavLink의 isActive를 활용한 스타일링도 다른 메뉴 항목들과 일관성을 유지하고 있습니다.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (2)
frontend/src/components/Sidebar.jsx (2)
28-30:isLoggedIn불린 초기화는 개선 완료, 스토리지 변경 동기화는 추후 고려 가능
!!localStorage.getItem('accessToken')로 초기화한 부분 덕분에 상태 타입이 명확해진 점 좋습니다.다만 여전히 다른 탭에서 로그인/로그아웃을 했을 때 이 컴포넌트의 상태가 자동으로 갱신되지는 않으니, 필요하다면
storage이벤트를 통해 동기화를 거는 것도 고려해 볼 수 있습니다 (필수는 아니고 선택 사항).useEffect(() => { const handleStorageChange = () => { setIsLoggedIn(!!localStorage.getItem('accessToken')); }; window.addEventListener('storage', handleStorageChange); return () => window.removeEventListener('storage', handleStorageChange); }, []);
32-53: 로그아웃 실패 시 오류/성공 토스트가 동시에 떠서 UX가 헷갈릴 수 있습니다현재 구현에서는 로그아웃 API 실패 시:
catch에서toast.error('오류가 발생했습니다.')가 뜨고finally에서 항상toast.success('로그아웃 되었습니다.')가 한 번 더 뜹니다.사용자 입장에서는 실패인지 성공인지 판단하기 어려운 흐름이라, 실패 시에는 한 종류의 메시지만 보이는 게 더 자연스러워 보입니다.
예를 들어 아래처럼 에러 여부 플래그를 두고 성공 토스트를 조건부로 띄우면 UX가 개선됩니다:
const logout = async () => { const accessToken = localStorage.getItem('accessToken'); + let isError = false; try { await api.post( '/api/auth/logout', {}, { headers: { Authorization: `Bearer ${accessToken}`, }, } ); } catch { - toast.error('오류가 발생했습니다.'); + isError = true; + toast.error('오류가 발생했습니다.'); } finally { localStorage.removeItem('accessToken'); localStorage.removeItem('refreshToken'); setIsLoggedIn(false); navigate('/'); - toast.success('로그아웃 되었습니다.'); + if (!isError) { + toast.success('로그아웃 되었습니다.'); + } } };원하신다면 실패 케이스에서
"서버 통신에는 문제가 있었지만 로컬 로그아웃은 완료되었습니다."같은 문구로 단일 토스트만 노출하는 방향도 고려해 볼 수 있습니다.
🧹 Nitpick comments (2)
frontend/src/App.jsx (1)
23-25: ToastContainer 전역 배치 좋습니다. (선택 사항: 중복 토스트 제한 옵션 고려)루트(App) 레벨에
ToastContainer를 둔 선택이 적절해서,useAuthGuard나 사이드바 로그아웃에서 발생하는 토스트가 모든 라우트에서 잘 표시될 것 같습니다.다만, 인증 관련 토스트가 짧은 시간 안에 여러 번 떠서 UX가 번잡해질 수 있으니, 필요하다면
limit등의 옵션으로 동시에 보여줄 토스트 개수를 제한하는 것도 한 번 고려해 보세요.<ToastContainer position="top-center" autoClose={2000} hideProgressBar={false} pauseOnHover theme="light" + limit={2} />Also applies to: 50-56
frontend/src/components/Sidebar.jsx (1)
155-208: 계정 섹션 조건부 렌더링은 적절하며, 로그아웃은 버튼 시맨틱도 고려 가능
isLoggedIn에 따라 ‘마이페이지/로그아웃’ vs ‘로그인/회원가입’을 토글하는 구조는 직관적이고, 전체 UX 흐름도 목적에 잘 맞습니다.다만 로그아웃 항목은 실제로는 “페이지 이동”보다는 “액션(상태 변경)”에 가까워서, 접근성/시맨틱을 신경 쓴다면
NavLink대신<button>또는 역할이 명확한 요소로 구현하고, 스타일만 링크처럼 맞추는 방안도 고려해 볼 수 있습니다. 필수는 아니고, 팀 스타일 가이드를 보고 결정하셔도 될 것 같습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
frontend/src/App.jsx(2 hunks)frontend/src/components/Sidebar.jsx(3 hunks)frontend/src/hooks/useAuthGuard.js(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- frontend/src/hooks/useAuthGuard.js
🔇 Additional comments (1)
frontend/src/components/Sidebar.jsx (1)
4-5: axios 래퍼와 toast import 방향 괜찮습니다공용
api인스턴스와react-toastify의toast를 여기서 직접 사용하는 구조는 사이드바의 로그아웃 책임에 잘 맞습니다. 별도 우려되는 부분은 없습니다.
1) 작업한 이슈번호
SISC1-214
2) 변경 요약 (What & Why)
3) 스크린샷/동영상 (UI 변경 시)
4) 상세 변경사항 (전부 다)
5) 참고사항
출석, 게시판, 백테스팅, 퀀트봇 페이지는 출동 위험이 있어 로그인 여부 검사 로직을 추가하지 않았습니다.
Summary by CodeRabbit
새로운 기능
보안·접근 제어
UI
오류 처리
✏️ Tip: You can customize this high-level summary in your review settings.