-
Notifications
You must be signed in to change notification settings - Fork 1
refactor: Apple JWT 인증 시스템 리팩토링 및 키 파싱 안정화 #63
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
…ervice로 변경하여 역할을 명확히 함
…l에 Kakao 및 Apple OAuth 설정 추가
…uthVO로 변경 및 updateAppleRefreshToken 메서드 추가
Walkthrough애플 로그인 인증 흐름이 전면적으로 리팩토링되었습니다. authorizationCode가 idToken과 함께 프론트엔드에서 서버로 전달되며, 서버는 client_secret을 생성해 authorizationCode와 함께 애플 서버에 전달하여 access/refresh 토큰을 발급받고, refresh 토큰을 DB에 저장하도록 구현이 변경되었습니다. 관련 서비스, 매니저, DTO, 예외 코드, 설정 파일, 빌드 설정, 인프라 계층, 프론트엔드 예제 등이 대거 수정 및 추가되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant FE as 프론트엔드
participant API as AuthController/UseCase
participant STR as AuthStrategyResolver
participant APPLE as AppleAuthService/AppleApiManager
participant DOMAIN as UserDomainService
participant INFRA as AppleApi/AppleRestClient
FE->>API: 소셜 로그인 요청 (idToken, authorizationCode 포함)
API->>STR: 인증 전략 결정 및 인증
STR->>API: 인증 결과 (user info)
API->>DOMAIN: 신규 유저 생성/조회
API->>APPLE: (AppleAuthCredentials일 때) refresh token 저장 요청
APPLE->>APPLE: refresh token 존재 여부 확인
APPLE->>INFRA: refresh token 없을 시, client_secret 생성 후 애플 서버에 토큰 요청
INFRA-->>APPLE: access/refresh token 응답
APPLE->>DOMAIN: refresh token DB 저장
API->>API: 토큰 생성 (access/refresh)
API-->>FE: 토큰 페어 응답
Estimated code review effort🎯 5 (Critical) | ⏱️ ~70 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
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: 15
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (45)
apis/build.gradle.kts(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthController.kt(0 hunks)apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthControllerApi.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/dto/request/FindOrCreateUserRequest.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/dto/request/SaveAppleRefreshTokenRequest.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/dto/request/SocialLoginRequest.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/dto/request/TermsAgreementRequest.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/dto/response/CreateUserResponse.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/helper/AppleJwtHelper.kt(0 hunks)apis/src/main/kotlin/org/yapp/apis/auth/helper/KakaoApiHelper.kt(0 hunks)apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleClientSecretGenerator.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleIdTokenProcessor.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/manager/AppleApiManager.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/manager/KakaoApiManager.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/AppleAuthService.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/AuthTokenService.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/RefreshTokenService.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/strategy/AppleAuthStrategy.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/strategy/AuthCredentials.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/strategy/AuthStrategyResolver.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/strategy/KakaoAuthStrategy.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/usecase/AuthUseCase.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/util/AppleKeyParser.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/util/generateNickname.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/book/exception/BookErrorCode.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/book/exception/UserBookErrorCode.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/config/AppleJwtConfig.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/config/AppleOauthProperties.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/config/AuthConfig.kt(1 hunks)apis/src/main/resources/application.yml(1 hunks)buildSrc/src/main/kotlin/Dependencies.kt(2 hunks)domain/src/main/kotlin/org/yapp/domain/book/exception/BookErrorCode.kt(1 hunks)domain/src/main/kotlin/org/yapp/domain/token/exception/TokenErrorCode.kt(1 hunks)domain/src/main/kotlin/org/yapp/domain/user/User.kt(6 hunks)domain/src/main/kotlin/org/yapp/domain/user/UserDomainService.kt(5 hunks)domain/src/main/kotlin/org/yapp/domain/user/exception/UserErrorCode.kt(1 hunks)domain/src/main/kotlin/org/yapp/domain/user/vo/UserAuthVO.kt(1 hunks)gateway/src/main/kotlin/org/yapp/gateway/config/JwtConfig.kt(3 hunks)infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/AppleApi.kt(1 hunks)infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/AppleRestClient.kt(1 hunks)infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/response/AppleTokenResponse.kt(1 hunks)infra/src/main/kotlin/org/yapp/infra/user/entity/UserEntity.kt(5 hunks)
💤 Files with no reviewable changes (3)
- apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthController.kt
- apis/src/main/kotlin/org/yapp/apis/auth/helper/KakaoApiHelper.kt
- apis/src/main/kotlin/org/yapp/apis/auth/helper/AppleJwtHelper.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-validation
🔇 Additional comments (71)
buildSrc/src/main/kotlin/Dependencies.kt (1)
12-14: 새로운 Spring dependencies 추가 승인OAuth2 클라이언트 지원과 설정 프로세서 추가가 Apple JWT 인증 시스템 리팩토링 목적에 잘 부합합니다.
apis/src/main/kotlin/org/yapp/apis/book/exception/UserBookErrorCode.kt (2)
7-7: 에러 코드 표준화 개선 승인property 이름을
httpStatus로 변경하여 의미가 더 명확해졌습니다.
12-12: 에러 코드 형식 개선 승인HTTP 상태 코드를 포함한 에러 코드 형식(
USER_BOOK_404_01)으로 변경하여 디버깅이 더 용이해졌습니다.apis/src/main/kotlin/org/yapp/apis/auth/util/generateNickname.kt (1)
1-1: 인증 관련 유틸리티 패키지 재구성 승인
NicknameGenerator를auth.util패키지로 이동하여 코드 구조가 더 논리적으로 개선되었습니다.apis/src/main/kotlin/org/yapp/apis/auth/dto/request/FindOrCreateUserRequest.kt (1)
6-6: import 경로 업데이트 승인
NicknameGenerator의 새로운 패키지 경로로 import가 올바르게 업데이트되었습니다.apis/src/main/kotlin/org/yapp/apis/auth/service/RefreshTokenService.kt (1)
12-12: 클래스 이름 개선 승인
TokenService에서RefreshTokenService로 변경하여 클래스의 책임이 더 명확해졌습니다. 리프레시 토큰 처리에 특화된 역할이 잘 드러납니다.apis/src/main/kotlin/org/yapp/apis/auth/strategy/AuthCredentials.kt (1)
15-20: Apple OAuth 인증 강화를 위한 올바른 구조 변경입니다.
authorizationCode속성 추가는 PR 목표와 완벽히 일치하며, Apple OAuth 2.0 인증 코드 플로우를 지원하기 위해 필요한 변경사항입니다. 이를 통해 서버에서 액세스 토큰과 리프레시 토큰을 교환할 수 있게 됩니다.apis/build.gradle.kts (3)
14-14: Apple OAuth 통합을 위한 적절한 의존성 추가입니다.Spring Boot OAuth2 클라이언트 스타터는 새로운 Apple OAuth 플로우 구현에 필요한 적절한 선택입니다.
25-25: 설정 프로퍼티 지원을 위한 적절한 어노테이션 프로세서 추가입니다.새로 도입된
AppleOauthProperties와 같은 설정 클래스들의 컴파일 타임 메타데이터 생성을 지원합니다.
22-23: BouncyCastle 버전(1.78.1) 취약점 확인 및 최신 버전 안내
- buildSrc/src/main/kotlin/Dependencies.kt
• BC_PROV, BC_PKIX 모두 “1.78.1” 사용 중- gh API 조회 결과
• 1.78 미만(≤1.77.x) 범위의 주요 취약점(무한 루프, 타이밍 공격, DoS 등)은 1.78에서 패치됨- Maven 중앙 저장소 최신 버전은 1.81
• 보안·안정성 강화를 위해 필요 시 1.81로 업그레이드 고려 바랍니다apis/src/main/kotlin/org/yapp/apis/book/exception/BookErrorCode.kt (1)
13-16: 에러 코드 표준화가 잘 적용되었습니다.HTTP 상태 코드를 포함한 새로운 에러 코드 형식(
BOOK_404_01,BOOK_500_01)은 디버깅과 에러 추적을 더욱 명확하게 만듭니다. 이는 애플리케이션 전반의 에러 처리 표준화와 일치하는 좋은 개선사항입니다.apis/src/main/kotlin/org/yapp/apis/config/AuthConfig.kt (1)
1-8: Apple OAuth 설정을 위한 깔끔한 구성 클래스입니다.
@EnableConfigurationProperties어노테이션을 통해AppleOauthProperties바인딩을 활성화하는 적절한 Spring Boot 설정 패턴을 따르고 있습니다. 단순하고 명확한 책임 분리가 이루어졌습니다.gateway/src/main/kotlin/org/yapp/gateway/config/JwtConfig.kt (3)
11-11: Import 추가가 적절합니다.
@Primary어노테이션 사용을 위한 필요한 임포트입니다.
53-56: Bean 충돌 해결을 위한 적절한@Primary어노테이션 사용입니다.Apple OAuth 전용 JWT 인코더와 일반 JWT 인코더가 공존할 때 발생할 수 있는 Bean 모호성을 해결하는 올바른 접근방식입니다. 기존 JWT 기능을 기본값으로 유지하면서 Apple 전용 빈은 필요한 곳에서만 사용되도록 합니다.
65-72: JWT 디코더에 대한@Primary어노테이션이 적절히 적용되었습니다.일반 JWT 디코더를 기본 빈으로 설정하여 Apple OAuth JWT 디코더와의 충돌을 방지합니다. 기존 JWT 검증 로직은 그대로 유지되면서 새로운 Apple 전용 JWT 처리와 완벽히 분리됩니다.
domain/src/main/kotlin/org/yapp/domain/user/exception/UserErrorCode.kt (2)
7-7: LGTM!속성명을
status에서httpStatus로 변경하여 더 명확한 의미를 제공합니다.
12-12: 오류 코드 표준화가 잘 되었습니다.오류 코드를
"USER_001"에서"USER_404_01"로 변경하여 HTTP 상태 코드를 포함한 더 설명적인 형식으로 개선되었습니다.apis/src/main/kotlin/org/yapp/apis/auth/strategy/KakaoAuthStrategy.kt (3)
8-9: LGTM!
KakaoApiHelper에서KakaoApiManager로의 전환과NicknameGeneratorimport 경로 업데이트가 적절합니다.
15-15: 의존성 주입 업데이트가 올바릅니다.생성자에서
KakaoApiHelper를KakaoApiManager로 교체하여 새로운 매니저 클래스를 사용합니다.
25-25: 메서드 호출 업데이트 확인 완료.
kakaoApiHelper.getUserInfo에서kakaoApiManager.getUserInfo로 메서드 호출이 올바르게 업데이트되었습니다.apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthControllerApi.kt (1)
24-131: API 문서 한국어 번역이 잘 완료되었습니다.모든 Swagger/OpenAPI 어노테이션이 일관되고 전문적인 한국어로 번역되었습니다. 사용자 친화적인 API 문서화에 도움이 될 것입니다.
domain/src/main/kotlin/org/yapp/domain/user/vo/UserAuthVO.kt (1)
6-20: 깔끔한 Value Object 구현입니다!새로운
UserAuthVO클래스가 잘 설계되었습니다:
- Apple 사용자가 아닌 경우를 고려한 nullable
appleRefreshToken처리- 팩토리 메서드를 통한 깔끔한 객체 생성 캡슐화
- 적절한 데이터 클래스 활용
apis/src/main/kotlin/org/yapp/apis/auth/strategy/AuthStrategyResolver.kt (1)
1-18: 클래스 리팩토링이 잘 수행되었습니다.
SocialAuthService에서AuthStrategyResolver로의 이름 변경과 패키지 이동이 적절합니다:
- 클래스의 실제 책임을 더 명확하게 반영하는 네이밍
- strategy 패키지로의 이동으로 더 나은 구조적 분리
- 기존 인터페이스를 유지하면서 깔끔한 리팩토링
apis/src/main/kotlin/org/yapp/apis/auth/dto/response/CreateUserResponse.kt (1)
25-36: Apple 리프레시 토큰 지원을 위한 DTO 확장이 올바르게 구현되었습니다.새로운 필드 추가와 팩토리 메서드 업데이트가 적절합니다:
- nullable 필드로 Apple 사용자가 아닌 경우를 올바르게 처리
- 명확한 Swagger 문서화로 API 사용자에게 정확한 정보 제공
UserAuthVO로의 전환이 새로운 인증 구조와 일관성 있게 적용apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleClientSecretGenerator.kt (2)
20-36: Apple JWT 클라이언트 시크릿 생성 로직이 올바르게 구현되었습니다.Apple OAuth 명세에 따른 필수 클레임들이 정확히 설정되어 있고, ES256 알고리즘과 5분 만료 시간도 적절합니다. JWT 인코더의 의존성 주입도 올바르게 처리되었습니다.
17-18: @qualifier 사용으로 명확한 빈 식별이 가능합니다.
@Qualifier("appleJwtEncoder")를 통해 Apple 전용 JWT 인코더를 명시적으로 지정한 것이 좋습니다. 이는 다른 JWT 인코더와의 충돌을 방지합니다.apis/src/main/kotlin/org/yapp/apis/auth/service/AuthTokenService.kt (2)
12-16: 서비스 계층 리팩토링이 적절히 수행되었습니다.
@Helper에서@Service로 변경하고RefreshTokenService의존성으로 업데이트한 것이 올바릅니다. 아키텍처 개선에 부합하는 변경사항입니다.
25-42: 의존성 변경이 일관되게 적용되었습니다.모든 메서드에서
tokenService에서refreshTokenService로의 변경이 일관되게 적용되었습니다. 메서드 로직은 그대로 유지되면서 새로운 서비스 구조에 맞게 업데이트되었습니다.apis/src/main/kotlin/org/yapp/apis/auth/manager/AppleApiManager.kt (2)
20-37: Apple OAuth 토큰 조회 로직이 잘 구현되었습니다.에러 핸들링과 로깅이 적절하며, 성공 시 ID 토큰을 20자로 제한하여 로깅하는 것도 보안상 좋은 관행입니다. Result 타입을 활용한 에러 처리도 깔끔합니다.
33-35: 적절한 예외 처리 및 에러 코드 사용원본 에러를 로깅하면서 사용자에게는 구체적인 에러 메시지와 함께
OAUTH_SERVER_ERROR코드를 제공하는 것이 보안과 사용성 측면에서 적절합니다.apis/src/main/kotlin/org/yapp/apis/auth/dto/request/SocialLoginRequest.kt (2)
33-38: Apple 로그인을 위한 인증 코드 필드 추가가 적절합니다.스키마 문서화도 명확하고, Apple 로그인에만 필요하다는 점이 잘 설명되어 있습니다. nullable 필드로 설정한 것도 다른 소셜 로그인과의 호환성을 위해 적절합니다.
56-60: Apple 제공자에 대한 인증 코드 검증이 올바르게 구현되었습니다.Apple 로그인 시 인증 코드가 없으면 명확한 에러 메시지와 함께
INVALID_REQUEST예외를 던지는 것이 적절합니다. 에러 처리가 명확하고 사용자 친화적입니다.apis/src/main/kotlin/org/yapp/apis/auth/manager/KakaoApiManager.kt (2)
18-44: Kakao API 매니저 구현이 우수합니다.에러 타입별로 적절한 예외 코드를 매핑하고(
HttpClientErrorException→INVALID_OAUTH_TOKEN,HttpServerErrorException→OAUTH_SERVER_ERROR), 성공 시 사용자 ID를 포함한 로깅도 잘 구현되었습니다. Result 타입을 활용한 함수형 에러 처리도 깔끔합니다.
26-42: 포괄적인 예외 처리 로직클라이언트 에러와 서버 에러를 구분하여 처리하고, 예상치 못한 예외는 그대로 재던지는 것이 적절합니다. 각 케이스별로 적절한 에러 코드와 메시지를 제공합니다.
apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt (4)
12-12: UserAuthVO로의 변경이 적절합니다.
UserIdentityVO에서UserAuthVO로의 변경이 Apple refresh token 지원을 위한 도메인 모델 확장과 일치합니다.
45-47: 반환 구조 개선이 좋습니다.기존 사용자 발견 시 바로 반환하는 로직이 명확하고 효율적입니다.
52-55: 복원 로직 타입 확인 완료
UserDomainService.restoreDeletedUser메서드의 반환 타입이UserAuthVO로 확인되었으므로,restoredUser변수의 타입 일치에 대한 추가 검증은 필요 없습니다.
61-61: 메서드 시그니처 일치 확인됨
createNewUser의 반환 타입(UserAuthVO)이UserDomainService.createUser의 반환 타입(UserAuthVO)과 일치합니다. 추가 검증이나 수정이 필요 없습니다.apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt (3)
19-25: 리소스 존재 여부 검증이 적절합니다.파일 존재 여부를 확인하고 명확한 에러 메시지를 제공하는 것이 좋습니다.
AuthErrorCode.FAILED_TO_LOAD_PRIVATE_KEY코드 사용도 적절합니다.
27-27: 리소스 자동 해제 처리가 우수합니다.
bufferedReader().use를 사용하여 InputStream을 안전하게 처리하는 것이 좋습니다.
29-29: AppleKeyParser.parseKeyPair 구현 확인 완료AppleKeyParser 파일에서
parseKeyPair(pemString: String): KeyPair메서드가 의도한 대로 정의되어 있음을 확인했습니다.
– apis/src/main/kotlin/org/yapp/apis/auth/util/AppleKeyParser.kt (36–44)추가 조치가 필요 없습니다.
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleIdTokenProcessor.kt (2)
10-14: 의존성 주입 구조가 적절합니다.
@Qualifier를 사용한 특정 JWT 디코더 주입과 ObjectMapper 사용이 적절합니다.
22-26: 데이터 클래스 구조가 적절합니다.Apple ID 토큰의 핵심 클레임인
sub와domain/src/main/kotlin/org/yapp/domain/token/exception/TokenErrorCode.kt (2)
7-7: 프로퍼티 이름 변경이 일관성을 향상시킵니다.
status에서httpStatus로의 이름 변경이 더 명확하고 다른 도메인 에러 코드들과의 일관성을 향상시킵니다.Also applies to: 16-16
12-14: HTTP 상태 코드를 포함한 에러 코드 표준화에러 코드에 HTTP 상태 코드를 포함시킨 것(예:
TOKEN_404_01,TOKEN_401_01)이 에러 식별과 처리를 개선합니다. 이는 일관된 에러 코드 체계 구축에 도움이 됩니다.domain/src/main/kotlin/org/yapp/domain/book/exception/BookErrorCode.kt (2)
7-7: 프로퍼티 이름 개선이 잘 되었습니다.
status에서httpStatus로 변경하여 의미가 더 명확해졌습니다.
12-13: 에러 코드 표준화가 적절합니다.HTTP 상태 코드 기반 형식(
BOOK_404_01,BOOK_409_01)으로 변경하여 에러 코드의 의미가 더 명확해졌습니다.infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/AppleRestClient.kt (2)
14-16: 상수 정의가 적절합니다.Apple OAuth 엔드포인트와 콘텐츠 타입이 올바르게 정의되었습니다.
32-39: 토큰 취소 메서드 구현이 올바릅니다.
toBodilessEntity()사용으로 응답 본문이 없는 경우를 적절히 처리하고 있습니다.domain/src/main/kotlin/org/yapp/domain/user/User.kt (3)
18-18: Apple 리프레시 토큰 프로퍼티 추가가 적절합니다.nullable로 정의하고 기본값을 null로 설정한 것이 합리적입니다.
37-41: 토큰 업데이트 메서드 구현이 일관성 있습니다.다른 업데이트 메서드와 동일한 패턴을 따르며, copy()를 사용해 불변성을 유지하고 있습니다.
60-62: 팩토리 메서드 업데이트가 올바릅니다.새로운 프로퍼티를 모든 팩토리 메서드에서 일관성 있게 처리하고 있습니다.
infra/src/main/kotlin/org/yapp/infra/user/entity/UserEntity.kt (3)
42-42: 생성자 파라미터 추가가 적절합니다.기본값을 null로 설정하여 기존 코드와의 호환성을 유지했습니다.
62-64: 데이터베이스 컬럼 정의가 적절합니다.최대 길이 1024자로 설정한 것이 JWT 리프레시 토큰을 저장하기에 충분합니다.
75-75: 도메인 매핑이 완전히 구현되었습니다.
toDomain()과fromDomain()메서드 모두에서 appleRefreshToken이 올바르게 매핑되고 있습니다.Also applies to: 91-91
infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/AppleApi.kt (3)
11-19: OAuth 파라미터 상수 정의가 적절합니다.매직 스트링을 방지하고 유지보수성을 향상시킵니다.
21-37: OAuth 토큰 요청 메서드가 잘 구현되었습니다.Result 타입을 사용한 에러 처리와 기본 파라미터 설정이 좋습니다.
39-55: 토큰 취소 메서드 구현이 올바릅니다.OAuth 표준에 맞는 파라미터 구성과 Result 타입을 통한 일관된 에러 처리가 적절합니다.
apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt (2)
13-21: 잘 구성된 에러 코드 추가입니다!Apple OAuth 통합을 위한 에러 코드들이 일관된 형식으로 잘 추가되었습니다. HTTP 상태 코드별로 명확하게 구분되어 있고, 에러 메시지도 구체적입니다.
33-37: 서버 내부 오류 코드가 적절하게 추가되었습니다Apple 인증 관련 서버 오류 처리를 위한 에러 코드들이 잘 정의되었습니다. 특히 개인키 로딩 실패나 외부 프로바이더 통신 실패 등 구체적인 상황별 에러 코드가 있어 디버깅에 유용할 것 같습니다.
apis/src/main/kotlin/org/yapp/apis/auth/strategy/AppleAuthStrategy.kt (1)
20-28: 깔끔한 리팩토링입니다!
AppleJwtHelper를AppleIdTokenProcessor로 교체하면서 코드가 더 간결해졌습니다. 명시적인 try-catch 블록을 제거하고 검증 성공 로깅을 추가한 것도 좋은 개선사항입니다.apis/src/main/kotlin/org/yapp/apis/config/AppleJwtConfig.kt (1)
17-47: 잘 구성된 JWT 설정입니다EC 키 쌍을 사용한 JWKSource 생성이 적절하게 구현되었습니다.
@Qualifier어노테이션 사용으로 빈 충돌을 방지한 것도 좋습니다.apis/src/main/kotlin/org/yapp/apis/auth/dto/request/SaveAppleRefreshTokenRequest.kt (1)
14-34: 잘 구성된 DTO 클래스입니다private constructor와 factory 메서드 패턴을 사용한 것이 좋습니다. validation 어노테이션도 적절하게 사용되었습니다.
apis/src/main/kotlin/org/yapp/apis/auth/util/AppleKeyParser.kt (2)
27-44: 포괄적인 키 파싱 구현입니다다양한 PEM 형식을 지원하고 적절한 예외 처리가 구현되어 있습니다. BouncyCastle을 활용한 안전한 키 처리가 잘 되어 있습니다.
123-128: EC 포인트 정규화 및 검증이 적절합니다EC 포인트를 정규화하고 무한대 점인지 확인하는 것은 보안상 중요한 검증입니다. 잘 구현되었습니다.
domain/src/main/kotlin/org/yapp/domain/user/UserDomainService.kt (3)
26-29: 메서드 반환 타입 변경이 적절합니다.
UserIdentityVO에서UserAuthVO로의 변경은 Apple 리프레시 토큰을 포함한 추가 인증 정보를 반환하기 위한 올바른 선택입니다.
47-63: 메서드 이름 변경과 반환 타입 업데이트가 잘 되었습니다.
createNewUser에서createUser로의 이름 변경은 더 간결하고 명확합니다.UserAuthVO반환은 다른 메서드들과 일관성을 유지합니다.
81-88: 새로운 Apple 리프레시 토큰 업데이트 메서드가 추가되었습니다.메서드 구현은 표준 패턴을 잘 따르고 있습니다. 다만, 다른 메서드들이
UserAuthVO를 반환하는 반면 이 메서드는UserIdentityVO를 반환합니다. 이것이 의도적인 선택인지 확인이 필요합니다.apis/src/main/kotlin/org/yapp/apis/auth/usecase/AuthUseCase.kt (3)
19-23: 의존성 주입 구조가 크게 개선되었습니다.레거시 헬퍼 클래스들을 제거하고 책임이 명확히 분리된 서비스들로 교체한 것은 좋은 리팩토링입니다. 특히
AuthStrategyResolver를 통한 전략 패턴 적용과 토큰 관련 책임의 분리가 잘 되어 있습니다.
33-41: Apple 리프레시 토큰 저장 로직이 잘 구현되었습니다.
AppleAuthCredentials타입 체크를 통한 조건부 처리가 적절합니다. 다만,saveAppleRefreshTokenIfMissing메서드의 실패 시 에러 처리가 어떻게 되는지 확인이 필요할 수 있습니다.
47-54: 토큰 재발급 로직이 명확하게 분리되었습니다.검증과 삭제가 별도의 메서드로 분리되어 각 단계가 명확해졌습니다.
authTokenService로 토큰 관련 작업이 중앙화된 것도 좋은 설계입니다.
apis/src/main/kotlin/org/yapp/apis/auth/dto/request/SaveAppleRefreshTokenRequest.kt
Show resolved
Hide resolved
apis/src/main/kotlin/org/yapp/apis/auth/dto/request/TermsAgreementRequest.kt
Show resolved
Hide resolved
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleIdTokenProcessor.kt
Show resolved
Hide resolved
| private val appleProperties: AppleOauthProperties, | ||
| private val resourceLoader: ResourceLoader, | ||
| ) { | ||
| val keyPair: KeyPair = loadKeyPair() |
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.
🧹 Nitpick (assertive)
즉시 로딩 방식의 보안 고려사항
생성자에서 즉시 키를 로드하는 방식은 애플리케이션 시작 시 키 파일 문제를 빠르게 감지할 수 있어 좋습니다. 하지만 메모리에 개인키가 계속 유지되므로 보안상 주의가 필요합니다.
향후 확장성을 위해 lazy loading 방식도 고려해볼 수 있습니다:
-val keyPair: KeyPair = loadKeyPair()
+val keyPair: KeyPair by lazy { loadKeyPair() }📝 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.
| val keyPair: KeyPair = loadKeyPair() | |
| val keyPair: KeyPair by lazy { loadKeyPair() } |
🤖 Prompt for AI Agents
In apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt
at line 16, the private key is loaded immediately in the constructor, which
keeps it in memory and may pose security risks. To address this, refactor the
code to use lazy loading for the keyPair property so that the key is only loaded
when first accessed, reducing the time it remains in memory and improving
security and extensibility.
apis/src/main/kotlin/org/yapp/apis/auth/service/AppleAuthService.kt
Outdated
Show resolved
Hide resolved
infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/AppleRestClient.kt
Show resolved
Hide resolved
infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/response/AppleTokenResponse.kt
Show resolved
Hide resolved
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
♻️ Duplicate comments (1)
apis/src/main/resources/application.yml (1)
35-44: 필수 환경변수 런타임 검증 필요
이전에 동일 지적이 있었듯,${APPLE_CLIENT_ID}등 필수 env 값이 누락되면 런타임에 NPE나 400 오류가 발생합니다. 애플 OAuth 초기화 시점에 값 존재 여부를 검증하고, 없으면 애플리케이션을 fail-fast 방식으로 종료하도록 하면 운영 사고를 예방할 수 있습니다.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (6)
apis/src/main/kotlin/org/yapp/apis/auth/dto/request/FindOrCreateUserRequest.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/RefreshTokenService.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/util/NicknameGenerator.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/book/exception/BookErrorCode.kt(1 hunks)apis/src/main/resources/application.yml(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-validation
🔇 Additional comments (10)
apis/src/main/kotlin/org/yapp/apis/book/exception/BookErrorCode.kt (1)
12-15: 에러 코드 포맷 변경에 따른 호출부 검증 필요
"BOOK_001"→"BOOK_500_01"(등) 로 포맷이 변경되면서, 기존에 문자열 기반으로code값을 비교‧로그‧모니터링하던 곳이 있다면 런타임에 매칭이 실패할 수 있습니다.
주요 사용처(예: API 응답 래퍼, 모니터링 대시보드, 클라이언트 측 매핑 로직)를 한 번 더 점검해 주세요.apis/src/main/kotlin/org/yapp/apis/auth/service/RefreshTokenService.kt (1)
15-15: RefreshTokenService로 클래스명 변경 및 의존성 업데이트가 올바르게 적용되었습니다.
기존TokenService참조는 더 이상 존재하지 않으며, 모든 사용처가RefreshTokenService로 정확히 치환된 것을 확인했습니다.apis/src/main/kotlin/org/yapp/apis/auth/dto/request/FindOrCreateUserRequest.kt (1)
7-7: 모든 파일에NicknameGeneratorimport 경로가 일관되게 변경되었습니다.검증 결과:
- 이전 경로(
org.yapp.apis.util.NicknameGenerator) 사용 파일 없음- 새로운 경로(
org.yapp.apis.auth.util.NicknameGenerator)가 다음 파일에서 확인됨:
- apis/src/main/kotlin/org/yapp/apis/auth/dto/request/FindOrCreateUserRequest.kt
- apis/src/main/kotlin/org/yapp/apis/auth/strategy/KakaoAuthStrategy.kt
- apis/src/main/kotlin/org/yapp/apis/auth/strategy/AppleAuthStrategy.kt
추가 조치가 필요하지 않습니다.
apis/src/main/kotlin/org/yapp/apis/auth/util/NicknameGenerator.kt (2)
3-25: 한국어 닉네임 생성 로직이 잘 유지되었습니다.다양한 한국어 형용사와 명사를 조합하여 친근하고 재미있는 닉네임을 생성하는 기능이 그대로 보존되어 있습니다. 패키지 이동에도 불구하고 핵심 기능은 변경되지 않았습니다.
1-1: 파일 물리적 위치 확인 완료 및 패키지 이동 승인
NicknameGenerator.kt가 오직
apis/src/main/kotlin/org/yapp/apis/auth/util/NicknameGenerator.kt
경로에만 존재하며 이전 패키지 위치에는 더 이상 남아 있지 않음을 확인했습니다.
인증 관련 유틸리티 재구성을 위해 패키지 이동을 그대로 승인합니다.apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt (5)
14-14: VO 타입 변경이 일관성 있게 적용되었습니다.
UserIdentityVO에서UserAuthVO로의 변경이 Apple JWT 인증 시스템 리팩토링의 일환으로 적절히 적용되었습니다.
48-50: 가독성 향상을 위한 적절한 리팩토링입니다.기존의
it을 직접 반환하던 방식에서 명시적으로 반환하는 방식으로 변경되어 코드의 가독성이 향상되었습니다.
55-57: 삭제된 사용자 복원 로직의 명확성이 개선되었습니다.복원된 사용자를 별도 변수에 할당한 후 반환하는 방식으로 변경되어 로직의 명확성이 크게 향상되었습니다. 이는 디버깅과 코드 이해에 도움이 됩니다.
64-64: 메서드 시그니처 변경이 도메인 리팩토링과 일치합니다.반환 타입이
UserAuthVO로 변경되어 전체적인 VO 타입 통일화 작업과 일관성을 유지합니다.
72-78: 도메인 서비스 메서드명 변경 확인 완료
domain/src/main/kotlin/org/yapp/domain/user/UserDomainService.kt에서 기존createNewUser가 제거되고fun createUser(…)가 정의되어 있으므로
UserAuthService내의userDomainService.createUser호출 변경은 올바르게 반영된 상태입니다.
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: 5
🔭 Outside diff range comments (2)
.github/workflows/ci-pr.yml (1)
28-35: APPLE_AUTH_KEY 저장 시 printf 사용 및 워크플로 중복 추출 권장Apple Private Key(
APPLE_AUTH_KEY)는 PEM 형식의 멀티라인 문자열이므로echo대신printf '%s'를 사용해 다음 문제를 방지하세요.
또한 동일한 블록이 세 개의 워크플로 파일에 중복되어 있으므로 Composite Action으로 추출해 유지보수를 쉽게 만드실 것을 권장합니다.변경 예시 (ci-pr.yml 기준):
- echo "${{ secrets.APPLE_AUTH_KEY }}" > ./secret/AuthKey.p8 + printf '%s' "${{ secrets.APPLE_AUTH_KEY }}" > ./secret/AuthKey.p8중복 위치:
- .github/workflows/ci-pr.yml
- .github/workflows/dev-ci-cd.yml
- .github/workflows/prod-ci-cd.yml
위 세 파일에서 동일한 스크립트 블록을 추출해 재사용 가능한 Composite Action으로 분리해 보세요.
apis/src/main/resources/static/kakao-login.html (1)
111-111: Kakao 키 설정이 누락되었습니다.
KAKAO_JS_KEY가 빈 문자열로 설정되어 있어 카카오 로그인이 실패할 수 있습니다.실제 환경에서는 유효한 Kakao JavaScript 키를 설정해야 합니다:
- const KAKAO_JS_KEY = ''; + const KAKAO_JS_KEY = 'YOUR_KAKAO_JS_KEY';
♻️ Duplicate comments (4)
.github/workflows/prod-ci-cd.yml (1)
27-33:APPLE_AUTH_KEY작성 로직 중복 / 개행 처리 동일 이슈앞서 CI-PR 워크플로와 동일하게
echo사용으로 인한 PEM 키 개행 문제 및 중복 코드가 존재합니다.
printf '%s'로 교체 후, 공통 step을 재사용하도록 고려해 주세요..github/workflows/dev-ci-cd.yml (1)
27-33: Dev 환경 워크플로에도 동일 수정 필요
echo→printf변경 및 공통 스크립트화 제안을 Dev-CI/CD에도 동일하게 적용해야 일관성이 확보됩니다.apis/src/main/kotlin/org/yapp/apis/auth/service/AppleAuthService.kt (2)
18-27: 예외 처리 및 트랜잭션 관리가 필요합니다.Apple API 호출과 도메인 서비스 업데이트에 대한 예외 처리가 부족하고, 트랜잭션 경계 설정이 필요합니다. 이전 리뷰에서 지적된 사항들이 아직 해결되지 않았습니다.
18-27: 예외 처리 및 트랜잭션 관리가 누락되었습니다.이전 리뷰 코멘트에서 지적된 다음 사항들이 아직 해결되지 않았습니다:
fetchAppleOauthTokens호출 시 네트워크 장애나 인증 실패 예외 처리 누락- Apple API 호출과 도메인 서비스 업데이트 간 트랜잭션 경계 미설정
- 리프레시 토큰 평문 저장으로 인한 보안 위험
이러한 문제들을 해결해주시기 바랍니다.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (14)
.github/workflows/ci-pr.yml(1 hunks).github/workflows/dev-ci-cd.yml(1 hunks).github/workflows/prod-ci-cd.yml(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/AppleAuthService.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/AuthTokenService.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/RefreshTokenService.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt(2 hunks)apis/src/main/kotlin/org/yapp/apis/readingrecord/exception/ReadingRecordErrorCode.kt(1 hunks)apis/src/main/resources/static/kakao-login.html(2 hunks)domain/src/main/kotlin/org/yapp/domain/readingrecord/exception/ReadingRecordErrorCode.kt(1 hunks)domain/src/main/kotlin/org/yapp/domain/userbook/exception/UserBookErrorCode.kt(1 hunks)global-utils/src/main/kotlin/org/yapp/globalutils/exception/CommonErrorCode.kt(1 hunks)infra/src/main/resources/application-external.yml(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-validation
🔇 Additional comments (28)
domain/src/main/kotlin/org/yapp/domain/userbook/exception/UserBookErrorCode.kt (2)
6-15:status필드 명칭이 리팩토링된 다른 enum들과 불일치합니다다른 오류 코드 enum(
BookErrorCode,UserErrorCode,TokenErrorCode등)은 필드명을httpStatus로 변경했지만, 본 파일은 여전히status를 사용하고 있어 일관성이 깨집니다. 통일성을 위해 필드명과 접근 메서드를 함께 수정해 주세요.-enum class UserBookErrorCode( - private val status: HttpStatus, +enum class UserBookErrorCode( + private val httpStatus: HttpStatus, private val code: String, private val message: String ) : BaseErrorCode { @@ - override fun getHttpStatus(): HttpStatus = status + override fun getHttpStatus(): HttpStatus = httpStatusLikely an incorrect or invalid review comment.
11-11: 에러 코드 포맷 통일 완료 👍
"USER_BOOK_404_01"형식으로 HTTP Status를 접두어로 포함하도록 변경한 부분은 다른 모듈과의 포맷 일관성을 맞추는 작업으로 확인됩니다. 별다른 문제 없습니다.domain/src/main/kotlin/org/yapp/domain/readingrecord/exception/ReadingRecordErrorCode.kt (1)
11-11: 에러 코드 변경 검증 결과 및 추가 확인 요청레포 전체에서 기존 에러 코드
"READING_RECORD_001"는 검색되지 않았습니다.
하지만 아래 위치에서 하드코딩 또는 DB 저장 값 등 참조가 남아있지 않은지 수동으로 최종 확인해 주세요.
- 서비스 로직 및 단위/통합 테스트
- 프론트엔드 매핑 테이블
- 데이터베이스에 저장된 에러 코드
- 로그 파서 및 로그 분석 도구 설정
위 항목을 모두 점검한 후 이상이 없다면 변경 사항을 안전하게 배포하실 수 있습니다.
apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt (5)
14-14: LGTM! 일관된 네이밍 변경
UserIdentityVO에서UserAuthVO로의 임포트 변경이 전체 리팩토링 목표와 일치합니다.
48-50: LGTM! 기존 사용자 처리 로직 유지기존 사용자가 발견된 경우의 처리 로직이 올바르게 유지되고 있습니다.
55-57: LGTM! 코드 가독성 개선변수명이
deletedUserAuth로 일관되게 변경되었고, 복원된 사용자를 변수에 할당한 후 반환하도록 리팩토링하여 가독성이 향상되었습니다.
64-64: LGTM! 메서드 시그니처 개선
@Valid어노테이션 추가로 입력 검증이 명시적으로 강화되었고, 반환 타입이UserAuthVO로 일관되게 변경되었습니다.
72-72: LGTM! 메서드명 단순화도메인 서비스의 메서드명이
createNewUser에서createUser로 단순화되어 더 명확해졌습니다.apis/src/main/kotlin/org/yapp/apis/readingrecord/exception/ReadingRecordErrorCode.kt (2)
11-11: 표준 오류 코드 체계 반영 완료HTTP 상태 코드(404) 프리픽스를 포함하도록 문자열이 수정되어 프로젝트 전반의 에러 코드 포맷과 일관성이 맞춰졌습니다. 👍
11-11: 에러 코드 중복 없음 확인 완료
전체.kt파일에서"XXX_YYY_ZZ"형식의 에러 코드를 검색한 결과 중복 항목이 없습니다. 추가 검토나 조치는 필요하지 않습니다.infra/src/main/resources/application-external.yml (2)
5-13: OAuth 설정 구조가 잘 설계되었습니다.민감한 정보들이 환경 변수로 외부화되어 보안성이 확보되었고, Apple의 audience URL이 고정값으로 설정된 것도 적절합니다.
5-13: OAuth 설정 구조가 적절합니다.환경 변수를 통한 민감 정보 외부화와 Apple OAuth 설정이 올바르게 구성되어 있습니다.
audienceURL은 Apple의 표준 엔드포인트이므로 하드코딩이 적절합니다.apis/src/main/kotlin/org/yapp/apis/auth/service/RefreshTokenService.kt (4)
15-15: 클래스명 변경이 적절합니다.
TokenService에서RefreshTokenService로 변경하여 클래스의 책임을 더 명확하게 표현했습니다.
40-40: 입력 검증 강화가 좋습니다.
@Valid어노테이션 추가로 요청 객체의 유효성 검증이 강화되었습니다.
15-15: 클래스명 변경이 적절합니다.
TokenService에서RefreshTokenService로 이름을 변경하여 서비스의 책임이 더 명확해졌습니다.
40-40: 입력 검증 강화가 좋습니다.
@Valid어노테이션 추가로 요청 객체의 입력 검증이 강화되었습니다.apis/src/main/resources/static/kakao-login.html (4)
124-127: 카카오 로그인 요청 포맷팅이 개선되었습니다.가독성이 향상되었고 기능적으로는 동일합니다.
143-199: Apple 로그인 구현이 크게 개선되었습니다.
- Authorization code 기반 OAuth 플로우로 정확히 구현됨
- 팝업 모드에서 안정적인
responseType: 'code'및responseMode: 'query'설정- 보안을 위한 state 파라미터 사용
- Authorization code 검증 로직 추가
- 향상된 에러 처리 (HTTP 상태 코드 확인, JSON 파싱)
- 상세한 성공 정보 표시
이러한 변경사항들이 백엔드의 새로운 Apple OAuth 인프라와 잘 연동됩니다.
201-240: 콜백 처리 로직이 잘 구현되었습니다.페이지 로드 시 Apple OAuth 콜백 파라미터를 감지하고 처리하는 로직이 견고합니다:
- URL 쿼리 파라미터에서 code와 state 추출
- state 값 검증을 통한 보안 강화
- 적절한 에러 처리 및 URL 정리
- 팝업과 리다이렉트 모드 모두 지원
201-240: 콜백 처리 로직이 잘 구현되었습니다.Apple OAuth 콜백 감지, 요청 처리, URL 정리 로직이 적절하게 구현되어 있습니다. 에러 처리와 사용자 피드백도 잘 되어 있습니다.
apis/src/main/kotlin/org/yapp/apis/auth/service/AuthTokenService.kt (7)
14-19: 서비스 구조가 잘 설계되었습니다.
RefreshTokenService와JwtTokenService를 조합하여 토큰 관리의 책임을 명확하게 분리했습니다.
20-33: 토큰 페어 생성 로직이 체계적입니다.
- 입력 검증을 통한 안전성 확보
- Access token과 refresh token 순차 생성
- Refresh token 저장까지 한 번에 처리
- 명확한 응답 객체 반환
토큰 생성과 저장이 원자적으로 처리되어 일관성이 보장됩니다.
35-38: 토큰 검증 로직이 적절합니다.검증과 사용자 ID 조회를 순차적으로 수행하여 안전성을 확보했습니다.
40-46: 토큰 삭제 메서드들이 명확합니다.재발급과 로그아웃에 대한 삭제 로직을 별도 메서드로 분리하여 의도가 명확하고, 향후 다른 로직이 필요할 경우 확장이 용이합니다.
16-19: 서비스 구조가 잘 설계되었습니다.
RefreshTokenService와JwtTokenService간의 의존성 분리가 명확하고, 토큰 생성과 관리 책임이 적절하게 분담되어 있습니다.
20-33: 토큰 생성 로직이 체계적입니다.access token과 refresh token을 순차적으로 생성하고, refresh token을 저장소에 저장하는 플로우가 올바르게 구현되어 있습니다. 입력 검증도 적절히 적용되었습니다.
40-46: 토큰 삭제 메서드들이 명확합니다.재발급용과 로그아웃용 토큰 삭제 메서드가 명확하게 분리되어 있어 코드의 의도가 잘 드러납니다.
apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt (1)
6-49: 잘 구현되었습니다! 👍에러 코드가 HTTP 상태별로 체계적으로 정리되었고, 새로운 명명 규칙(AUTH_STATUS_XX)이 일관되게 적용되었습니다. Apple OAuth 관련 에러들도 적절히 추가되었네요.
global-utils/src/main/kotlin/org/yapp/globalutils/exception/CommonErrorCode.kt
Show resolved
Hide resolved
- ApplePrivateKeyLoader를 Mocking하여 테스트가 파일 시스템 의존성 없이 독립적으로 실행될 수 있도록 격리했습니다.
…키 이름을 하이픈 형식으로 변경
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: 7
🔭 Outside diff range comments (1)
apis/src/main/resources/application.yml (1)
88-89: 불필요한 빈 줄 제거 필요파일 끝에 불필요한 빈 줄이 있습니다.
audience: https://appleid.apple.com -
♻️ Duplicate comments (3)
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt (3)
18-18: 보안 고려사항: 메모리 내 개인키 보관생성자에서 즉시 키를 로드하는 방식은 애플리케이션 시작 시 키 파일 문제를 빠르게 감지할 수 있어 좋지만, 메모리에 개인키가 계속 유지되어 보안상 위험할 수 있습니다.
보안성 향상을 위해 lazy loading 방식을 고려해보세요:
-val keyPair: KeyPair = loadKeyPair() +val keyPair: KeyPair by lazy { loadKeyPair() }
18-18: 메모리 보안 고려사항 (이전 리뷰 의견과 동일)생성자에서 즉시 키를 로드하여 메모리에 개인키가 지속적으로 유지되는 방식은 보안상 위험할 수 있습니다.
14-18: 메모리 내 개인키 보관에 대한 보안 검토 필요생성자에서 즉시 키를 로드하여 메모리에 지속적으로 보관하는 방식은 빠른 실패 감지에는 좋지만, 보안상 위험할 수 있습니다. 이전 리뷰에서도 지적된 사항입니다.
-val keyPair: KeyPair = loadKeyPair() +val keyPair: KeyPair by lazy { loadKeyPair() }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt(1 hunks)apis/src/main/resources/application.yml(1 hunks)apis/src/test/kotlin/org/yapp/apis/ApisApplicationTests.kt(1 hunks)apis/src/test/kotlin/org/yapp/apis/BaseIntegrationTest.kt(1 hunks)apis/src/test/kotlin/org/yapp/apis/config/MockTestConfiguration.kt(1 hunks)gateway/src/main/kotlin/org/yapp/gateway/security/SecurityConfig.kt(0 hunks)infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt(1 hunks)infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinRestClient.kt(2 hunks)infra/src/main/resources/application-external.yml(1 hunks)
💤 Files with no reviewable changes (1)
- gateway/src/main/kotlin/org/yapp/gateway/security/SecurityConfig.kt
🧰 Additional context used
🪛 YAMLlint (1.37.1)
apis/src/main/resources/application.yml
[error] 88-88: too many blank lines (1 > 0)
(empty-lines)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-validation
🔇 Additional comments (15)
apis/src/test/kotlin/org/yapp/apis/ApisApplicationTests.kt (1)
9-9: 테스트 인프라 구조화가 잘 되었습니다.
BaseIntegrationTest를 상속하여 공통 테스트 설정을 활용하는 것은 좋은 접근입니다. Apple OAuth 관련 모킹 설정을 포함한 통합 테스트 환경이 일관되게 적용됩니다.apis/src/test/kotlin/org/yapp/apis/BaseIntegrationTest.kt (1)
7-9: 통합 테스트 기반 클래스 구현이 깔끔합니다.
@Import(MockTestConfiguration::class)를 통해 Apple OAuth 관련 모킹 설정을 가져오는 구조가 적절합니다. 추상 클래스로 구현하여 공통 테스트 설정을 제공하면서 하위 클래스에서 확장 가능한 구조입니다.apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt (6)
1-11: 의존성 및 패키지 구조가 적절합니다.필요한 Spring Framework 컴포넌트와 커스텀 유틸리티 클래스들이 적절히 임포트되어 있습니다. Apple OAuth 통합을 위한 구조가 명확하게 설계되었습니다.
12-17: 프로파일 설정과 의존성 주입이 적절합니다.
@Profile("!test")어노테이션을 통해 테스트 환경에서는 제외되도록 하고, 실제 환경에서만 동작하도록 설정한 것이 좋습니다. 의존성 주입도 적절히 구성되어 있습니다.
20-32: 리소스 로딩 및 에러 처리가 잘 구현되었습니다.Spring의 ResourceLoader를 사용한 리소스 접근과 적절한 예외 처리가 구현되어 있습니다. 파일 존재 여부 검증과 명확한 에러 메시지 제공이 좋습니다.
bufferedReader().use패턴을 통한 안전한 리소스 해제도 적절합니다.
22-27: 리소스 존재 확인 및 에러 처리가 적절합니다파일 존재 여부를 확인하고 명확한 에러 메시지와 함께 커스텀 예외를 던지는 방식이 좋습니다. 애플리케이션 시작 시 설정 문제를 빠르게 감지할 수 있어 운영상 도움이 됩니다.
13-13: 테스트 프로필 제외 설정이 적절합니다
@Profile("!test")어노테이션으로 테스트 환경에서 실제 키 로딩을 방지하는 것이 좋은 접근입니다.
29-31: AppleKeyParser.parseKeyPair 예외 처리 로직 이미 존재AppleKeyParser.parseKeyPair 내부에서 모든 예외를 포괄적으로 잡아 IllegalArgumentException으로 래핑하여 던지고 있으므로, ApplePrivateKeyLoader 쪽에서 별도 예외 처리를 추가할 필요가 없습니다.
- 파일: apis/src/main/kotlin/org/yapp/apis/auth/util/AppleKeyParser.kt
- catch (e: Exception) { throw IllegalArgumentException("키 파싱 실패", e) } (라인 41–43)
Likely an incorrect or invalid review comment.
infra/src/main/resources/application-external.yml (4)
5-13: OAuth 설정이 적절히 구성되었습니다.Kakao와 Apple OAuth 설정이 체계적으로 구성되어 있습니다. 특히 다음 사항이 잘 처리되었습니다:
- 민감한 정보들이 환경변수로 적절히 외부화됨
- Apple의 고정 엔드포인트(
https://appleid.apple.com)는 하드코딩이 적절함- 설정 구조가 명확하고 확장 가능함
Apple OAuth 통합에 필요한 모든 필수 속성들이 포함되어 있어
AppleOauthProperties와의 매핑이 원활할 것으로 보입니다.
8-13: 환경변수 네이밍 규칙 확인 요청Apple OAuth 관련 환경변수들의 네이밍이 일관성 있게
APPLE_접두사를 사용하고 있어 좋습니다. 다만 실제 배포 환경에서 이러한 환경변수들이 올바르게 설정되어 있는지 확인이 필요합니다.특히
APPLE_KEY_PATH는 PEM 파일의 경로를 가리키므로, 파일 접근 권한과 경로 유효성을 검증해주세요.
5-13: OAuth 설정 구조가 잘 구성되어 있습니다민감한 정보(API 키, 클라이언트 ID 등)를 환경변수로 외부화하고, 고정값인 Apple audience URL만 하드코딩한 방식이 적절합니다. 설정 구조도 명확하게 계층화되어 있어
AppleOauthProperties와의 바인딩이 원활할 것으로 보입니다.
5-13: OAuth 설정 구조가 잘 설계되었습니다새로운 OAuth 설정이 체계적으로 구성되어 있고, 민감한 정보가 환경변수로 적절히 외부화되었습니다. Apple의 audience URL이 하드코딩된 것도 Apple의 고정 엔드포인트이므로 적절한 판단입니다.
apis/src/main/resources/application.yml (1)
81-87: OAuth Apple 설정 구조가 잘 정의됨kebab-case 네이밍 컨벤션을 일관되게 사용하여 가독성과 유지보수성이 향상되었습니다. 더미 값들도 개발/테스트 환경에서 적절하게 설정되어 있습니다.
infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinRestClient.kt (2)
19-19: 파라미터 타입 일관성 개선
ttbKey파라미터를String?에서String으로 변경하여AladinApi클래스의 변경사항과 일관성을 유지했습니다. null 체크가 불필요해져 코드가 더 간결해졌습니다.
35-35: 파라미터 타입 일관성 개선
itemLookUp메서드의ttbKey파라미터도 동일하게 non-nullable로 변경되어 API 전반의 타입 안전성이 향상되었습니다.
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt
Show resolved
Hide resolved
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt
Show resolved
Hide resolved
infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt
Outdated
Show resolved
Hide resolved
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
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt(1 hunks)apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleIdTokenProcessor.kt(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-validation
🔇 Additional comments (5)
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleIdTokenProcessor.kt (2)
11-16: 클래스 구조가 잘 설계되었습니다!의존성 주입과 한정자(Qualifier) 사용이 적절합니다.
28-32: 데이터 클래스가 적절하게 설계되었습니다!Apple의 이메일 숨김 기능을 고려하여 email 필드를 nullable로 처리한 것이 좋습니다.
apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt (3)
13-23: 400 에러 코드가 체계적으로 정리되었습니다!일관된 형식(AUTH_400_XX)과 명확한 한국어 메시지로 잘 구성되어 있습니다.
25-32: 인증/인가 에러 코드가 적절히 구분되었습니다!401(인증 실패)과 403(권한 부족)의 구분이 명확합니다.
37-50: 서버 에러 코드가 포괄적으로 정의되었습니다!Apple 인증 관련 서버 측 오류 시나리오가 잘 다루어졌습니다.
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleIdTokenProcessor.kt
Show resolved
Hide resolved
|
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: 3
♻️ Duplicate comments (2)
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt (2)
12-13: 프로파일 어노테이션 활용 검토
@Profile("!test")어노테이션으로 테스트 환경을 제외하는 것은 좋은 접근입니다. 하지만 통합 테스트에서도 실제 키 로딩 로직을 검증할 필요가 있을 수 있습니다.
18-18: 즉시 로딩 방식의 보안 고려사항생성자에서 즉시 키를 로드하는 방식은 애플리케이션 시작 시 키 파일 문제를 빠르게 감지할 수 있어 좋습니다. 하지만 메모리에 개인키가 계속 유지되므로 보안상 주의가 필요합니다.
향후 확장성을 위해 lazy loading 방식도 고려해볼 수 있습니다:
-val keyPair: KeyPair = loadKeyPair() +val keyPair: KeyPair by lazy { loadKeyPair() }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt(1 hunks)apis/src/main/resources/application.yml(1 hunks)infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt(1 hunks)infra/src/main/resources/application-external.yml(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
apis/src/main/resources/application.yml
[error] 88-88: too many blank lines (1 > 0)
(empty-lines)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-validation
🔇 Additional comments (4)
infra/src/main/resources/application-external.yml (1)
3-3: 네이밍 컨벤션 개선 잘 적용됨
ttbkey에서ttb-key로 kebab-case 네이밍 컨벤션으로 통일한 것이 좋습니다. 설정 파일 전체의 일관성이 향상되었습니다.apis/src/main/resources/application.yml (2)
77-79: 개발용 설정 추가 잘 구성됨Aladin API 설정이 적절한 dummy 값으로 추가되어 개발 환경에서 안전하게 사용할 수 있습니다.
81-87: Apple OAuth 개발용 설정이 체계적으로 구성됨Apple OAuth에 필요한 모든 설정이 적절한 placeholder 값으로 잘 구성되어 있습니다.
key-path의 "path-ignored-by-mock" 값은 테스트/개발 환경에서 모킹될 것임을 명확하게 표현하고 있어 좋습니다.infra/src/main/kotlin/org/yapp/infra/external/aladin/AladinApi.kt (1)
13-14: 타입 안전성 개선과 설정 연동이 잘 완료됨
ttbKey를 non-nullable로 변경하여 런타임 안전성이 크게 향상되었습니다. 또한 관련 설정 파일들(application.yml,application-external.yml)에 적절한 값들이 추가되어 과거 리뷰에서 우려했던 설정 누락 문제가 해결되었습니다. fail-fast 원칙에 따라 설정이 누락된 경우 애플리케이션 시작 시점에 명확한 오류가 발생하게 됩니다.


🔗 관련 이슈
📘 작업 유형
📙 작업 내역
Apple JWT 인증 시스템 전면 리팩토링
컴포넌트 구조 개선
AppleJwtHelper,AuthTokenHelper제거 (기존 레거시 코드)AppleIdTokenProcessor,ApplePrivateKeyLoader,AppleClientSecretGenerator신규 추가설정 및 구성 요소 개선
AppleJwtConfig,AppleOauthProperties신규 추가AppleAuthStrategy,AuthCredentials리팩토링AuthTokenService신규 구현으로 토큰 관리 로직 분리Apple OAuth 플로우 완전 구현
authorizationCode를 받아 Apple 서버와 토큰 교환 처리refreshToken을 User 엔티티에 안전하게 저장의존성 및 검증 로직 강화
AuthErrorCode확장으로 더 명확한 오류 메시지 제공🧪 테스트 내역
🎨 스크린샷 또는 시연 영상 (선택)
✅ PR 체크리스트
💬 추가 설명 or 리뷰 포인트
주요 개선 포인트
리뷰 포인트
AppleKeyParser.kt: BouncyCastle을 활용한 키 파싱 로직의 안전성AppleJwtConfig.kt: JWT 인코더/디코더 설정의 적절성AuthTokenService.kt: 토큰 관리 로직의 책임 분리가 적절한지AppleJwtHelper,AuthTokenHelper제거에 따른 영향도 검토브레이킹 체인지
질문
account_email을 받도록 설정해야 하는데 비즈 앱 전환을 하지 않는 이상 권한이 없어 테스트를 못하고 있는데, 혹시 민우님은 어떻게 테스트를 하셨는지 궁금합니다Summary by CodeRabbit
신규 기능
버그 수정
리팩터링
환경설정
테스트
기타