[Gibeom] Week9 미션#106
Conversation
[Gibeom] Week7 미션
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 088b79ed8e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| } | ||
| @Override | ||
| public String getUsername() { | ||
| return member.getSocialUid(); |
There was a problem hiding this comment.
MemberService.login()에서 new AuthMember(member)로 JWT를 만들고 있는데, 현재 AuthMember#getUsername()이 socialUid를 반환합니다. 일반 회원가입 사용자는 socialUid/socialType이 비어 있으므로 토큰의 subject/claim이 깨지고, 이후 JwtAuthFilter의 사용자 복원 흐름에서 인증이 실패해 로그인 후 보호 API를 사용할 수 없습니다. 일반 로그인과 소셜 로그인의 식별자 전략(예: 이메일 기반 vs 소셜 UID 기반)을 분리하고, 토큰 생성/파싱/조회 로직을 같은 기준으로 맞추는 쪽이 좋습니다. 다음으로 UserDetails의 username 의미와 JWT claim 설계를 함께 복습해 보세요.
Useful? React with 👍 / 👎.
| @GetMapping("/missions") | ||
| @GetMapping("/v1/members/missions") | ||
| public ResponseEntity<ApiResponse<List<MissionResDTO.MissionDto>>> getMissionsByStatus( | ||
| @AuthenticationPrincipal Long memberId, |
There was a problem hiding this comment.
미션 조회에서 principal 타입을 AuthMember로 통일하세요
JwtAuthFilter는 인증 성공 시 principal로 UserDetails(AuthMember)를 넣는데, getMissionsByStatus는 @AuthenticationPrincipal Long memberId를 받고 있습니다. 이 타입 불일치에서는 @AuthenticationPrincipal 값이 null이 되어 memberId가 비정상 전달되고(빈 결과 또는 예외), 같은 컨트롤러의 다른 메서드와도 인증 모델이 불일치합니다. AuthMember를 주입받아 ID를 꺼내 쓰도록 통일하면 레이어 책임과 인증 흐름이 명확해집니다. 다음 학습 포인트는 AuthenticationPrincipal 해석 방식과 SecurityContext principal 타입 일치입니다.
Useful? React with 👍 / 👎.
kjhh2605
left a comment
There was a problem hiding this comment.
[키워드 조사]
세션과 토큰의 차이, Access Token과 Refresh Token, OAuth 1.0과 2.0 차이를 예시 중심으로 정리한 점이 좋습니다. 다만 Refresh Token의 저장 위치와 재발급 흐름, JWT claim에 넣을 값과 넣지 말아야 할 값, Authorization Code Grant의 참여자 역할을 더 구체적으로 보완하는 것을 권장합니다.
[코드 리뷰]
JWT 유틸, JWT 필터, OAuth2 사용자 서비스, 성공 핸들러, 인증 사용자 기반 조회까지 Week9 인증 흐름을 폭넓게 구현했습니다. .env와 .idea 정리도 적절합니다. 다만 일반 로그인 토큰과 소셜 로그인 토큰의 subject/claim 해석이 한 필터에서 일관되게 처리되지 않고, 유사한 JWT 필터·유틸 패키지가 중복되어 유지보수성이 낮아질 수 있으므로 패키지 경계와 인증 주체 모델을 정리할 필요가 있습니다.
| if (jwtUtil.isValid(token)) { | ||
| // 토큰에서 이메일 추출 | ||
| String uid = jwtUtil.getUid(token); | ||
| SocialType socialType = jwtUtil.getSocialType(token); |
There was a problem hiding this comment.
일반 로그인에서 발급한 토큰에는 social_type이 없을 수 있는데, 현재 필터는 항상 socialType과 uid로 회원을 조회합니다. 일반 회원은 이메일 기준 조회, 소셜 회원은 socialType+socialUid 기준 조회처럼 토큰 종류별 조회 기준을 분기하는 것을 권장합니다.
| @@ -0,0 +1,72 @@ | |||
| package com.example.umc10th.global.filter; | |||
There was a problem hiding this comment.
유사한 JWT 필터가 global.filter와 global.security.filter에 함께 존재하면 실제로 어떤 필터를 사용하는지 파악하기 어려워집니다. 사용하지 않는 패키지를 제거하고 보안 관련 클래스는 한 패키지 경계로 모으는 것을 권장합니다.
|
|
||
| 액세스 토큰 : 접근하기 위해 필요한 기본적인 토큰, 해킹 공격 방지를 위해 유효기간이 짧다. | ||
|
|
||
| 리프레쉬 토큰 : 만료된 액세스 토큰을 재생성해주는 토큰. |
There was a problem hiding this comment.
Refresh Token을 “Access Token을 재생성해주는 토큰”으로만 설명하면 저장 위치, 만료 정책, 탈취 시 무효화 전략이 빠질 수 있습니다. 서버 저장 여부, 재발급 API 흐름, 회전 전략까지 함께 정리하는 것을 권장합니다.
🔗 연관 이슈
#105
🛠 작업 내용
🖼 스크린샷 (선택)
👀 리뷰 요구사항 (선택)
🤖 AI 활용
💬 나의 프롬프트
OAuth2 의존성 추가 후 ClientRegistrationRepository 빈을 찾을 수 없다는 에러 발생.
해결 후 접속했으나 카카오 화면에서 앱 관리자 설정 오류 (KOE101) 발생.
오류 URL 확인 시 client_id=${KAKAO_REST_API_KEY} 형태로 나감.
인텔리제이 프로그램 자체가 내부 오류 팝업을 띄우며 정상적으로 시작되지 않음.
🧠 AI 응답
YML 구조 오류: security: 설정이 jwt: 하위로 잘못 들여쓰기 되어 있어 스프링이 OAuth2 설정을 전혀 읽지 못함. spring: 하위 구조로 격상시켜 해결.
프로토콜 불일치: 카카오 디벨로퍼스에는 https://로, yml에는 http://로 리다이렉트 주소가 설정되어 대소문자/프로토콜 불일치로 차단됨 (http로 통일).
변수 파싱 실패: 인텔리제이가 .env 내부 변수를 yml로 치환하지 못해 문장 그대로 카카오 서버에 전송됨. 이 역시 인텔리제이 Environment variables(환경 변수)에 실제 카카오 REST API 키를 직접 등록하여 최종 해결함.
.env 파일을 편하게 보기 위해 설치했던 외부 플러그인(dotenv)이 현재 맥북의 인텔리제이 버전 또는 Java 26 버전과 충돌을 일으켜 프로그램 구동부에서 크래시가 발생함.
✅ 내가 최종 선택한 방법 (이유)
💡 나만의 Tip (선택)