Conversation
There was a problem hiding this comment.
Pull request overview
auth 도메인 리팩터링과 함께, 인증/보안 설정 및 외부 연동 클라이언트 구성을 정리하고 헬스체크 엔드포인트를 추가한 PR입니다.
Changes:
- 보안 허용 URL에
/health,/api/auth/logout추가 및 JWT 필터 제외 경로 동기화 - 애플 인증용
RestClientBean 추가 및 애플 클라이언트 어댑터 주입 대상 수정 - Auth/Verification 관련 DTO의 Swagger/Validation 메타데이터 보강 및 불필요 Config 제거
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/main/java/com/loopon/global/security/filter/JwtAuthenticationFilter.java | JWT 필터 제외 URL에 /health, /api/auth/logout 추가 |
| src/main/java/com/loopon/global/health/HealthCheckController.java | /, /health 헬스체크 컨트롤러 신규 추가 |
| src/main/java/com/loopon/global/config/SecurityConfig.java | PUBLIC_URL에 /health, /api/auth/logout 추가 및 배열 정리 |
| src/main/java/com/loopon/global/config/RestClientConfig.java | appleRestClient Bean 신규 추가 |
| src/main/java/com/loopon/global/config/HttpInterfaceConfig.java | 빈 Config 클래스 삭제 |
| src/main/java/com/loopon/auth/infrastructure/apple/AppleAuthClientAdapter.java | 애플 RestClient 사용으로 정리 |
| src/main/java/com/loopon/auth/application/dto/response/AuthResult.java | 토큰 응답 Swagger Schema 보강 |
| src/main/java/com/loopon/auth/application/dto/request/VerificationVerifyRequest.java | Validation 메시지 구체화 |
| src/main/java/com/loopon/auth/application/dto/request/VerificationRequest.java | Validation 메시지 구체화 |
| src/main/java/com/loopon/auth/application/dto/request/SocialLoginRequest.java | Validation 메시지 구체화 |
| src/main/java/com/loopon/auth/application/dto/request/PasswordResetRequest.java | Validation 메시지 구체화 |
| src/main/java/com/loopon/auth/application/dto/request/LoginRequest.java | 요청 DTO 포맷 정리(공백 라인) |
| import io.swagger.v3.oas.annotations.media.Schema; | ||
|
|
||
| public record AuthResult( | ||
| @Schema(description = "액세스 토큰 (Bearer)", example = "eyJhbGciOiJIUzI1NiJ9...") |
There was a problem hiding this comment.
🟡 논의 필요: accessToken의 Schema 설명이 "(Bearer)"로 되어 있어 응답 값 자체에 Bearer 접두어가 포함되는 것으로 오해될 수 있습니다. 실제로는 JWT 문자열만 내려주고 클라이언트가 Authorization: Bearer <token> 형태로 붙이는 구조라면, 설명을 "액세스 토큰(JWT). Authorization 헤더에는 Bearer 접두어를 붙여 전송"처럼 더 명확히 해주는 게 좋습니다.
| @Schema(description = "액세스 토큰 (Bearer)", example = "eyJhbGciOiJIUzI1NiJ9...") | |
| @Schema(description = "액세스 토큰(JWT). Authorization 헤더 전송 시 'Bearer ' 접두어를 붙여 사용", example = "eyJhbGciOiJIUzI1NiJ9...") |
| "/", | ||
| "/health", | ||
| "/favicon.ico", |
There was a problem hiding this comment.
🔴 반드시 수정: PUBLIC_URLS에 포함된 "/api/terms/{termId}"는 Spring Security의 Ant 패턴 매칭에서 PathVariable 템플릿으로 해석되지 않아 /api/terms/1 같은 실제 요청이 permitAll로 처리되지 않습니다. 단순히 */**로 치환하면 PATCH /api/terms/{termId}(약관 동의 수정)까지 공개될 수 있으니, HttpMethod.GET에 한정한 requestMatcher로 /api/terms와 /api/terms/*만 permitAll 처리하도록 분리하는 방식이 안전합니다.
| "/", | ||
| "/health", | ||
| "/favicon.ico", |
There was a problem hiding this comment.
🔴 반드시 수정: excludeUrlPatterns의 "/api/terms/{termId}"는 AntPathMatcher에서 PathVariable 템플릿으로 처리되지 않아 /api/terms/1에 매칭되지 않습니다. 또한 이 리스트는 HTTP method를 구분하지 않기 때문에, 와일드카드로 수정 시 PATCH /api/terms/{termId} 같은 인증 필요 API까지 필터가 스킵될 수 있습니다. 공개가 필요한 경우라도 shouldNotFilter에서 method까지 함께 검사하거나(예: GET만 스킵), 해당 패턴을 제외하는 형태로 정리하는 게 안전합니다.
| @GetMapping("/") | ||
| public ResponseEntity<CommonResponse<Map<String, String>>> systemStatus() { | ||
| Map<String, String> status = Map.of( | ||
| "status", "UP", | ||
| "profile", activeProfile, | ||
| "serverTime", LocalDateTime.now().toString(), | ||
| "message", "LoopOn API Server is running!" | ||
| ); |
There was a problem hiding this comment.
🟡 논의 필요: / 엔드포인트가 profile, serverTime 등을 포함한 상세 상태 정보를 인증 없이 반환하고 있고(SecurityConfig/JWT 필터에서도 public 처리), 운영 환경/프로파일 정보가 외부에 노출될 수 있습니다. 단순 헬스체크 목적이면 /health처럼 최소한의 고정 응답만 주거나, 상세 정보는 actuator/내부망/관리자 권한으로 제한하는 구성이 더 안전합니다.
| try { | ||
| return kakaoRestClient.post() | ||
| return appleRestClient.post() | ||
| .uri("https://appleid.apple.com/auth/token") |
There was a problem hiding this comment.
🟡 논의 필요: appleRestClient를 baseUrl("https://appleid.apple.com")로 빈 등록해두었는데, 여기서는 .uri("https://appleid.apple.com/auth/token")로 절대 URL을 다시 지정하고 있어 baseUrl 설정이 사실상 무의미해집니다. 상대 경로(/auth/token)를 사용하도록 맞추거나, 반대로 baseUrl 설정을 제거해 한 곳에서만 URL을 관리하도록 정리하는 편이 유지보수에 유리합니다.
| .uri("https://appleid.apple.com/auth/token") | |
| .uri("/auth/token") |
#⃣ 관련 이슈
Closes #164
📝 작업 내용
Check list
💬 리뷰 요구사항(선택)