Skip to content

Feature: 페이지 접근 보호 시스템 구축 및 레이아웃 통일#13

Open
woo-dev-log wants to merge 2 commits into
developfrom
feature/auth-interceptor
Open

Feature: 페이지 접근 보호 시스템 구축 및 레이아웃 통일#13
woo-dev-log wants to merge 2 commits into
developfrom
feature/auth-interceptor

Conversation

@woo-dev-log

Copy link
Copy Markdown
Contributor

📌 PR 종류 (PR Type)

  • 🐛 버그 수정 (Bugfix)
  • ✨ 기능 추가 (Feature)
  • 🎨 UI 스타일 변경 (Style) - CSS, 클래스명, 레이아웃 등 UI 변경
  • ♻️ 코드 리팩토링 (Refactor) - 기능 변화 없이 코드 구조 개선
  • 📦 패키지/빌드 관련 변경 (Build) - 설정 파일 수정, 의존성 추가 등
  • 🧱 테스트 코드 추가/수정 (Test)
  • 📝 문서 수정 (Docs)
  • 🚧 WIP (작업 중 PR)
  • 기타 (Other):

📝 요약 (Summary)

페이지 접근 보호를 위한 PrivateRoute 시스템 구축 및 공개 페이지 레이아웃 복구


🔍 상세 내용 (Describe your changes)

1. PrivateRoute 컴포넌트 구현

  • 로그인 인증 상태 체크 로직 추가하여 자동 로그인 페이지 리다이렉트 구현
  • React Router의 Navigate 컴포넌트를 활용한 선언적 리다이렉트

2. 라우터 구조 개선

  • App 컴포넌트를 PrivateRoute로 감싸 주요 페이지 보호
  • 로그인/콜백/온보딩 페이지는 공개 라우트로 분리
  • 인증이 필요한 페이지와 공개 페이지 명확히 구분

3. 레이아웃 이슈 해결

  • PrivateRoute 분리로 인해 공개 페이지에서 GlobalLayout이 적용되지 않는 문제 발생
  • 로그인 및 온보딩 페이지에 GlobalLayout 개별 적용
  • 모든 페이지에서 UI 일관성 확보

📸 스크린샷 (필수)

Before After
녹화_2025_08_05_16_26_53_696

✅ 확인 사항 (CheckList)

  • 브라우저에서 정상 동작 확인
  • 기존 기능에 영향 없음
  • 반응형 UI 대응 확인
  • 코드 컨벤션에 맞게 작성됨 (eslint, prettier 등)
  • 테스트 코드 추가/수정 또는 테스트 통과 확인

💬 기타 참고사항 (Optional)

테스트 방법

  • 로그아웃 상태에서 /, /explore, /my 등 접근 시 /login으로 리다이렉트 확인
    • 현재 로그아웃이 없어서 시크릿 모드로 테스트하면 될 것 같습니다!

추후 개선 예정

  • 현재 session_id로 인증 체크하고 있으나, 추후 access_token으로 통일 예정

- 로그인 인증 상태 체크 로직 추가
- App 컴포넌트를 PrivateRoute로 감싸 주요 페이지 보호
- 로그인/콜백/온보딩 페이지는 공개 라우트로 분리
- 로그인, 온보딩 페이지가 App 컴포넌트 밖으로 가면서 발생한 레이아웃 이슈 해결
- 로그인 페이지에 GlobalLayout 개별 적용
- 온보딩 페이지에 GlobalLayout 개별 적용
@github-actions github-actions Bot added ✨feature 기능 개발 🐞bugfix 버그 수정 labels Aug 5, 2025

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @woo-dev-log, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on enhancing the application's security by introducing a robust page access protection system. It involves creating a dedicated PrivateRoute component, restructuring the React Router configuration to enforce authentication for protected areas, and ensuring layout consistency across all pages, including public-facing ones.

Highlights

  • Authentication System: I've implemented a new PrivateRoute component that checks for user authentication (currently via session_id in localStorage) and automatically redirects unauthenticated users to the login page using React Router's Navigate component.
  • Router Structure Improvement: The application's routing has been refactored in src/main.tsx. The main <App /> component is now wrapped by the PrivateRoute, ensuring that all core application pages require authentication. Public routes like /login and /onboarding have been moved to the top level to allow unauthenticated access.
  • Layout Consistency for Public Pages: To address a layout issue where public pages lost their consistent UI after the routing changes, I've explicitly applied the GlobalLayout component to both LoginPage and OnboardingPage. This ensures a unified look and feel across all pages, while disabling header and bottom navigation for these specific public views.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

안녕하세요. 페이지 접근 보호를 위한 PrivateRoute 도입과 레이아웃 통일 작업을 잘 보았습니다. 인증이 필요한 라우트와 공개 라우트를 명확하게 분리하여 애플리케이션의 보안 구조를 강화한 점이 인상적입니다.

코드 리뷰는 프로젝트 스타일 가이드에 따라 한국어로 작성되었으며, 특히 테스트 코드 작성 의무화 (스타일 가이드 12번째 줄) 조항을 중점적으로 확인했습니다. 이를 바탕으로 몇 가지 개선점을 제안합니다.

  • 보안 강화: 현재 localStorage를 사용한 토큰 관리는 XSS 공격에 취약할 수 있습니다. httpOnly 쿠키를 사용하는 방안을 고려해보시는 것이 좋습니다.
  • 유지보수성 향상: 코드에 하드코딩된 문자열을 상수로 관리하고, 라우팅 구조 변경으로 인해 발생한 불필요한 코드를 정리하면 유지보수성이 향상될 것입니다.
  • 테스트 코드 추가: 스타일 가이드에 따라, 새로 추가된 PrivateRoute 컴포넌트에 대한 테스트 코드를 작성하여 로직의 안정성을 보장해야 합니다.

자세한 내용은 각 파일에 남긴 코멘트를 확인해주세요.

export const PrivateRoute = ({ children }: PrivateRouteProps) => {
// TODO: 현재 백엔드에서 로그인 응답을 sessionId로 제공하고 있어
// 임시로 session_id로 인증 체크 중. 추후 access_token으로 통일 예정
const token = localStorage.getItem('session_id');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

보안 상 localStorage에 세션 ID와 같은 민감한 데이터를 저장하는 것은 XSS(Cross-Site Scripting) 공격에 취약점을 노출할 수 있습니다. localStorage는 JavaScript를 통해 쉽게 접근할 수 있어, 악성 스크립트가 주입될 경우 토큰이 탈취될 위험이 있습니다.

권장 사항:
httpOnly 속성을 적용한 쿠키를 사용하여 토큰을 관리하는 것을 강력히 권장합니다. httpOnly 쿠키는 JavaScript로 접근할 수 없기 때문에 XSS 공격으로부터 토큰을 효과적으로 보호할 수 있습니다.

Comment on lines +8 to +14
export const PrivateRoute = ({ children }: PrivateRouteProps) => {
// TODO: 현재 백엔드에서 로그인 응답을 sessionId로 제공하고 있어
// 임시로 session_id로 인증 체크 중. 추후 access_token으로 통일 예정
const token = localStorage.getItem('session_id');

return token ? <>{children}</> : <Navigate to="/login" replace />;
}; No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

프로젝트 스타일 가이드에 따르면 모든 코드에 자동화된 테스트가 필요합니다.1 PrivateRoute 컴포넌트는 애플리케이션의 핵심 인증 로직을 담당하므로, 안정적인 동작을 보장하기 위한 테스트 코드를 작성하는 것이 매우 중요합니다.

아래와 같은 시나리오에 대한 테스트 케이스를 추가하는 것을 권장합니다.

  • 인증된 사용자: 토큰이 존재할 경우, children이 정상적으로 렌더링되는지 확인합니다.
  • 인증되지 않은 사용자: 토큰이 없을 경우, /login 경로로 올바르게 리다이렉트되는지 확인합니다.

Style Guide References

Footnotes

  1. 스타일 가이드에서는 모든 코드에 대한 자동화 테스트 작성을 의무화하고 있습니다. (link)

export const PrivateRoute = ({ children }: PrivateRouteProps) => {
// TODO: 현재 백엔드에서 로그인 응답을 sessionId로 제공하고 있어
// 임시로 session_id로 인증 체크 중. 추후 access_token으로 통일 예정
const token = localStorage.getItem('session_id');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

인증 토큰의 키로 사용된 'session_id'가 매직 문자열(magic string)로 하드코딩되어 있습니다. 이는 오타 발생 가능성을 높이고, 향후 키 이름이 변경될 경우 여러 곳을 수정해야 하는 등 유지보수를 어렵게 만듭니다.

별도의 상수 파일(예: src/constants/auth.ts)에 키를 상수로 정의하고 이를 가져와 사용하는 것이 좋습니다. 이렇게 하면 코드의 가독성과 안정성이 크게 향상됩니다.

개선 예시:

// src/constants/auth.ts
export const AUTH_TOKEN_KEY = 'session_id';

// src/components/auth/PrivateRoute.tsx
import { AUTH_TOKEN_KEY } from '@/constants/auth';
// ...
const token = localStorage.getItem(AUTH_TOKEN_KEY);

Comment thread src/main.tsx
Comment on lines +72 to +83
{
path: "/login",
element: <LoginPage />,
},
{
path: "/callback",
element: <AuthCallbackPage />,
},
{
path: "/onboarding",
element: <OnboardingPage />,
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

로그인 및 온보딩 페이지를 App 컴포넌트의 하위 라우트에서 최상위 라우트로 분리한 구조 변경은 페이지 접근 제어를 명확하게 만들어주는 좋은 시도입니다.

다만 이로 인해 App.tsx 파일 내 layoutGroups 객체에 정의된 /login/onboarding 경로에 대한 레이아웃 분기 로직이 더 이상 사용되지 않는 코드가 되었습니다. 코드의 혼란을 방지하고 유지보수성을 높이기 위해, App.tsx에서 해당 경로 관련 코드를 제거하는 후속 조치가 필요해 보입니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐞bugfix 버그 수정 ✨feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant