-
Notifications
You must be signed in to change notification settings - Fork 0
feat: proxy(middleware) 설정 추가 #235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- accessToken과 refreshToken이 둘다 없으면 login 페이지로 redirect: /mypage, /post-meetup, /message, /schedule - login 로직 수정(withCredentials 속성 추가) - token.ts 로직 수정(Domain 속성 추가)
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough인증 시스템을 개선하여 쿠키 기반 자격증명 처리를 추가했습니다. 로그인 API에 withCredentials를 활성화하고, 액세스 토큰에 도메인을 지정한 후, 보호된 경로에 대한 미들웨어 기반 접근 제어를 구현했습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as 클라이언트
participant Middleware as 미들웨어<br/>(proxy.ts)
participant AuthAPI as 인증 API
participant TokenStore as 토큰 저장소<br/>(token.ts)
participant ProtectedRoute as 보호된 경로
rect rgb(220, 240, 255)
Note over Client,ProtectedRoute: 로그인 흐름
Client->>AuthAPI: POST /auth/login<br/>(withCredentials: true)
AuthAPI-->>Client: accessToken 반환
Client->>TokenStore: setAccessToken 호출
TokenStore->>TokenStore: 쿠키 설정<br/>(domain=.wego.monster)
end
rect rgb(240, 220, 255)
Note over Client,ProtectedRoute: 보호된 경로 접근
Client->>Middleware: /mypage 요청
Middleware->>Middleware: 토큰 존재 여부 확인
alt 토큰 존재
Middleware->>ProtectedRoute: 요청 허용
ProtectedRoute-->>Client: 페이지 렌더링
else 토큰 없음
Middleware-->>Client: /login?error=unauthorized<br/>로 리다이렉트
end
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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 |
🎨 Storybook Report✅ 변경 사항이 없습니다 모든 Story가 이전 빌드와 동일합니다.
|
🎭 Playwright Report✨ E2E Test가 성공적으로 완료되었습니다. Test 요약 내용을 확인해주세요.
📊 Test Summary
📜 Test Details✅ Passed Tests (3)
|
📊 Coverage Report
📉 #235을 main에 병합하면 coverage가 Coverage 요약@@ Coverage Diff @@
## main #235 +/- ##
===========================================
- Coverage 38.24% 38.08% -0.16%
===========================================
Files 175 176 +1
Lines 7574 7606 +32
Branches 330 331 +1
===========================================
Hits 2897 2897 0
+ Misses 4677 4709 +32 영향받은 파일
|
🚀 PR Preview Report✨ Build가 성공적으로 완료되었습니다. Preview에서 변경사항을 확인하세요.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/api/service/auth-service/index.ts (2)
24-27: 로그아웃 요청에 withCredentials 추가가 필요합니다.서버에서 쿠키(refreshToken)를 사용하여 세션을 무효화하는 경우,
withCredentials: true옵션이 필요합니다. 이것이 없으면 서버 측 세션이 제대로 정리되지 않을 수 있습니다.🔎 제안하는 수정
logout: async () => { - await api.post<void>('/auth/logout'); + await api.post<void>('/auth/logout', {}, { withCredentials: true }); clearAccessToken(); },
42-45: 회원 탈퇴 요청에 withCredentials 추가가 필요합니다.로그아웃과 동일하게, 서버에서 쿠키 기반 인증을 사용하는 경우
withCredentials: true옵션을 추가해야 합니다.🔎 제안하는 수정
withdraw: async () => { - await api.delete<void>('/auth/withdraw'); + await api.delete<void>('/auth/withdraw', { withCredentials: true }); clearAccessToken(); },src/lib/auth/token.ts (1)
19-23: 쿠키 삭제 시 도메인 속성이 누락되었습니다.쿠키를 제대로 삭제하려면 설정 시 사용한 도메인과 경로를 정확히 일치시켜야 합니다.
setAccessToken에서domain=.wego.monster를 설정했으므로,clearAccessToken에서도 동일한 도메인을 지정해야 합니다. 그렇지 않으면 쿠키가 제대로 삭제되지 않아 로그아웃이 실패할 수 있습니다.🔎 제안하는 수정
export const clearAccessToken = () => { if (typeof document === 'undefined') return; - document.cookie = `${ACCESS_TOKEN_KEY}=; Max-Age=0; path=/`; + document.cookie = `${ACCESS_TOKEN_KEY}=; Max-Age=0; path=/; domain=.wego.monster`; };
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/api/service/auth-service/index.tssrc/lib/auth/token.tssrc/proxy.ts
🧰 Additional context used
🧬 Code graph analysis (1)
src/api/service/auth-service/index.ts (2)
src/api/core/index.ts (1)
api(114-114)src/types/service/auth.ts (1)
LoginResponse(19-28)
🔇 Additional comments (4)
src/api/service/auth-service/index.ts (1)
14-14: 쿠키 기반 인증을 위한 올바른 설정입니다.
withCredentials: true추가는 쿠키를 포함한 크로스 오리진 요청을 가능하게 하며, refresh 함수와 일관성을 유지합니다.src/lib/auth/token.ts (1)
6-10: 서브도메인 간 쿠키 공유를 위한 올바른 설정입니다.
domain=.wego.monster추가로 모든 서브도메인에서 액세스 토큰을 사용할 수 있습니다. 다만,clearAccessToken함수도 동일한 도메인 속성으로 업데이트되어야 합니다 (아래 리뷰 참조).src/proxy.ts (2)
4-13: 보호된 경로 정의가 명확합니다.쿠키에서 토큰을 가져오고 보호된 경로를 확인하는 로직이 올바르게 구현되었습니다.
startsWith를 사용하여 중첩된 경로도 적절히 처리합니다.
27-29: 매처 설정이 적절합니다.API 라우트, 정적 파일, 인증 관련 페이지를 올바르게 제외하고 있습니다. Next.js 미들웨어의 표준 패턴을 따릅니다.
| if (!accessToken && !refreshToken) { | ||
| const loginUrl = new URL('/login', request.url); | ||
| loginUrl.searchParams.set('error', 'unauthorized'); | ||
| loginUrl.searchParams.set('path', request.nextUrl.pathname); | ||
| return NextResponse.redirect(loginUrl); | ||
| } | ||
|
|
||
| // accessToken 있으면 통과 | ||
| return NextResponse.next(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
인증 로직에 불일치와 토큰 갱신 로직이 누락되었습니다.
현재 로직의 문제점:
- 16번 줄의 조건
!accessToken && !refreshToken은 둘 중 하나라도 존재하면 24번 줄로 진행합니다. 하지만 23번 줄의 주석은 "accessToken 있으면 통과"라고 명시하고 있어 의도가 불명확합니다. - accessToken이 없고 refreshToken만 있는 경우, 토큰 갱신을 시도하지 않고 그냥 통과시킵니다. 이 경우 보호된 페이지에서 API 호출 시 401 에러가 발생할 수 있습니다.
미들웨어에서 토큰 갱신을 처리하거나, 최소한 accessToken이 있을 때만 통과하도록 로직을 명확히 해야 합니다.
🔎 제안하는 수정 (옵션 1: accessToken 필수)
- // 둘 다 없으면 로그인
+ // 토큰이 없거나 accessToken이 없으면 로그인
- if (!accessToken && !refreshToken) {
+ if (!accessToken) {
const loginUrl = new URL('/login', request.url);
loginUrl.searchParams.set('error', 'unauthorized');
loginUrl.searchParams.set('path', request.nextUrl.pathname);
return NextResponse.redirect(loginUrl);
}
- // accessToken 있으면 통과
+ // accessToken이 있으면 통과
return NextResponse.next();🔎 제안하는 수정 (옵션 2: refreshToken으로 갱신 시도)
refreshToken이 있지만 accessToken이 없는 경우 토큰 갱신을 시도하는 로직을 추가할 수 있습니다. 다만 미들웨어에서 API 호출을 수행하면 복잡도가 증가하므로, 클라이언트 측에서 처리하는 것이 더 나을 수 있습니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!accessToken && !refreshToken) { | |
| const loginUrl = new URL('/login', request.url); | |
| loginUrl.searchParams.set('error', 'unauthorized'); | |
| loginUrl.searchParams.set('path', request.nextUrl.pathname); | |
| return NextResponse.redirect(loginUrl); | |
| } | |
| // accessToken 있으면 통과 | |
| return NextResponse.next(); | |
| if (!accessToken) { | |
| const loginUrl = new URL('/login', request.url); | |
| loginUrl.searchParams.set('error', 'unauthorized'); | |
| loginUrl.searchParams.set('path', request.nextUrl.pathname); | |
| return NextResponse.redirect(loginUrl); | |
| } | |
| // accessToken이 있으면 통과 | |
| return NextResponse.next(); |
wooktori
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤓🤓🤓🤓
| return NextResponse.next(); | ||
| } | ||
|
|
||
| export const config = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 경로들은 위의 프록시에서 제외되는 건가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
넵 맞아용
내장 next api,정적 자원 요청(이미지 등), 로그인, 회원가입 페이지는 proxy 동작이 필요없기 때문에 제외했습니다~
📝 변경 사항
/mypage,/post-meetup,/message,/schedule🔗 관련 이슈
Closes #
🧪 테스트 방법
📸 스크린샷 (선택)
📋 체크리스트
💬 추가 코멘트
CodeRabbit Review는 자동으로 실행되지 않습니다.
Review를 실행하려면 comment에 아래와 같이 작성해주세요
Summary by CodeRabbit
새로운 기능
보안 개선
✏️ Tip: You can customize this high-level summary in your review settings.