Skip to content

Conversation

@move-hoon
Copy link
Member

@move-hoon move-hoon commented Jul 30, 2025

🔗 관련 이슈

📘 작업 유형

  • ✨ Feature (기능 추가)
  • 🐞 Bugfix (버그 수정)
  • 🔧 Refactor (코드 리팩토링)
  • ⚙️ Chore (환경 설정)
  • 📝 Docs (문서 작성 및 수정)
  • ✅ Test (기능 테스트)
  • 🎨 style (코드 스타일 수정)

📙 작업 내역

Apple JWT 인증 시스템 전면 리팩토링

  • AppleKeyParser 신규 구현: Apple .p8 키 파일 파싱을 위한 안정적인 유틸리티 클래스
    • BouncyCastle 기반으로 PKCS#8, SEC1, OpenSSL 등 다양한 PEM 형식 지원
    • ECPoint 정규화 처리로 "point not in normal form" 오류 해결
    • 안전한 공개키 유도 로직 구현

컴포넌트 구조 개선

  • Apple 인증 헬퍼 클래스 재구성:
    • AppleJwtHelper, AuthTokenHelper 제거 (기존 레거시 코드)
    • AppleIdTokenProcessor, ApplePrivateKeyLoader, AppleClientSecretGenerator 신규 추가
    • 역할별로 명확하게 분리된 구조로 개선

설정 및 구성 요소 개선

  • Apple OAuth 설정 분리: AppleJwtConfig, AppleOauthProperties 신규 추가
  • 인증 전략 개선: AppleAuthStrategy, AuthCredentials 리팩토링
  • 토큰 서비스: AuthTokenService 신규 구현으로 토큰 관리 로직 분리

Apple OAuth 플로우 완전 구현

  • Authorization Code 기반 토큰 발급:
    • authorizationCode를 받아 Apple 서버와 토큰 교환 처리
    • 클라이언트 시크릿 동적 생성으로 보안 강화
  • Refresh Token 저장:
    • Apple에서 발급받은 refreshToken을 User 엔티티에 안전하게 저장
    • 회원탈퇴 지원: Apple 정책 준수를 위한 토큰 해지 API 호출 준비
    • 사용자가 앱 내에서 Apple 계정 연동 해제 시 Apple 서버에 토큰 무효화 요청 가능

의존성 및 검증 로직 강화

  • BouncyCastle 의존성 추가: EC 키 연산의 안정성 확보
  • Validator 패키지 추가: 입력값 검증 로직 체계화
  • 에러 처리 개선: AuthErrorCode 확장으로 더 명확한 오류 메시지 제공

🧪 테스트 내역

  • 브라우저/기기에서 동작 확인
  • 엣지 케이스 테스트 완료
  • 기존 기능 영향 없음

🎨 스크린샷 또는 시연 영상 (선택)

기능 미리보기 기능 미리보기
기능 설명 기능 설명

✅ PR 체크리스트

  • 커밋 메시지가 명확합니다
  • PR 제목이 컨벤션에 맞습니다
  • 관련 이슈 번호를 작성했습니다
  • 기능이 정상적으로 작동합니다
  • 불필요한 코드를 제거했습니다

💬 추가 설명 or 리뷰 포인트

주요 개선 포인트

  1. 안정성 향상: Apple .p8 키 파싱 시 발생하던 ECPoint 관련 오류 완전 해결
  2. 코드 품질: 기존 레거시 코드 제거하고 역할별로 명확히 분리된 클린 아키텍처 적용
  3. 유지보수성: Apple 인증 관련 로직이 체계적으로 구조화되어 향후 확장성 확보
  4. Apple 정책 준수: 회원탈퇴 기능 구현을 위한 Refresh Token 저장으로 Apple App Store 정책 완벽 대응

리뷰 포인트

  • AppleKeyParser.kt: BouncyCastle을 활용한 키 파싱 로직의 안전성
  • AppleJwtConfig.kt: JWT 인코더/디코더 설정의 적절성
  • AuthTokenService.kt: 토큰 관리 로직의 책임 분리가 적절한지
  • Apple Refresh Token 저장 로직: User 엔티티 확장 및 보안성 검토
  • Authorization Code 처리: Apple 서버와의 토큰 교환 플로우 검증
  • 기존 AppleJwtHelper, AuthTokenHelper 제거에 따른 영향도 검토

브레이킹 체인지

  • 기존 Apple 인증 관련 헬퍼 클래스들이 새로운 구조로 완전히 교체됨
  • User 엔티티에 Apple Refresh Token 필드 추가 (dev db에는 ddl-auto: update로 반영된 상황)
  • 외부에서 직접 참조하는 코드가 있다면 수정 필요 (내부 구현체이므로 영향 최소화 예상)
  • (중요)환경변수 업데이트 아직 안함!

질문

  • 현재 제 개인 앱에서 카카오 로그인 테스트를 하려했을 때 account_email을 받도록 설정해야 하는데 비즈 앱 전환을 하지 않는 이상 권한이 없어 테스트를 못하고 있는데, 혹시 민우님은 어떻게 테스트를 하셨는지 궁금합니다

Summary by CodeRabbit

  • 신규 기능

    • Apple OAuth 인증 기능 및 클라이언트 시크릿 JWT 생성 기능이 추가되었습니다.
    • Apple 리프레시 토큰 저장 및 관리 기능이 도입되었습니다.
    • Apple 및 카카오 OAuth API 연동 매니저가 새롭게 도입되어 안정성 및 구조가 개선되었습니다.
    • Apple OAuth 관련 설정, 키 파일 로딩 및 JWT 디코더/인코더 지원이 추가되었습니다.
    • 인증 토큰 생성, 검증, 삭제를 담당하는 AuthTokenService가 도입되었습니다.
    • Apple 및 카카오 인증 전략이 리팩터링되어 내부 구현이 변경되었습니다.
    • Apple OAuth 토큰 발급 및 토큰 폐기용 인프라 클라이언트가 추가되었습니다.
  • 버그 수정

    • 인증 관련 오류 코드 및 메시지가 HTTP 상태 코드 기반으로 표준화되었습니다.
    • API 문서(스웨거)의 한글화 및 설명이 개선되었습니다.
  • 리팩터링

    • 인증 및 토큰 관리 서비스가 역할별로 분리되어 구조가 개선되었습니다.
    • 기존 인증 헬퍼 클래스가 매니저 및 프로세서 클래스로 대체되었습니다.
    • 토큰 서비스명이 RefreshTokenService로 변경되고, 토큰 관리 책임이 명확해졌습니다.
    • 인증 전략 해석기(AuthStrategyResolver)로 인증 흐름이 재구성되었습니다.
    • 사용자 VO 타입이 UserIdentityVO에서 UserAuthVO로 변경되어 인증 정보가 확장되었습니다.
  • 환경설정

    • Apple OAuth 관련 외부 설정 프로퍼티 및 시크릿 키 파일 관리가 추가되었습니다.
    • CI/CD 워크플로우에 Apple 인증 키 파일 자동 주입이 반영되었습니다.
    • Aladin API 키 설정이 필수로 변경되어 누락 방지가 강화되었습니다.
  • 테스트

    • 통합 테스트용 베이스 클래스 및 Apple 키 로더 모킹 설정이 추가되었습니다.
  • 기타

    • 카카오 로그인 및 Apple 로그인 웹 UI가 팝업 및 리다이렉트 콜백을 지원하도록 개선되었습니다.
    • 일부 의존성 및 빌드 설정에 OAuth2 클라이언트 및 BouncyCastle 라이브러리가 추가되었습니다.

move-hoon added 30 commits July 29, 2025 01:34
@coderabbitai
Copy link

coderabbitai bot commented Jul 30, 2025

Walkthrough

애플 로그인 인증 흐름이 전면적으로 리팩토링되었습니다. authorizationCode가 idToken과 함께 프론트엔드에서 서버로 전달되며, 서버는 client_secret을 생성해 authorizationCode와 함께 애플 서버에 전달하여 access/refresh 토큰을 발급받고, refresh 토큰을 DB에 저장하도록 구현이 변경되었습니다. 관련 서비스, 매니저, DTO, 예외 코드, 설정 파일, 빌드 설정, 인프라 계층, 프론트엔드 예제 등이 대거 수정 및 추가되었습니다.

Changes

Cohort / File(s) Change Summary
애플 OAuth 인증 리팩토링
apis/src/main/kotlin/org/yapp/apis/auth/dto/request/SaveAppleRefreshTokenRequest.kt, apis/src/main/kotlin/org/yapp/apis/auth/dto/request/SocialLoginRequest.kt, apis/src/main/kotlin/org/yapp/apis/auth/dto/response/CreateUserResponse.kt, apis/src/main/kotlin/org/yapp/apis/auth/strategy/AuthCredentials.kt, apis/src/main/kotlin/org/yapp/apis/auth/service/AppleAuthService.kt, apis/src/main/kotlin/org/yapp/apis/auth/manager/AppleApiManager.kt, apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleClientSecretGenerator.kt, apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/AppleIdTokenProcessor.kt, apis/src/main/kotlin/org/yapp/apis/auth/helper/apple/ApplePrivateKeyLoader.kt, apis/src/main/kotlin/org/yapp/apis/auth/util/AppleKeyParser.kt, apis/src/main/kotlin/org/yapp/apis/auth/strategy/AppleAuthStrategy.kt, apis/src/main/kotlin/org/yapp/apis/auth/usecase/AuthUseCase.kt, apis/src/main/kotlin/org/yapp/apis/config/AppleJwtConfig.kt, apis/src/main/kotlin/org/yapp/apis/config/AppleOauthProperties.kt, apis/src/main/kotlin/org/yapp/apis/config/AuthConfig.kt, infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/AppleApi.kt, infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/AppleRestClient.kt, infra/src/main/kotlin/org/yapp/infra/external/oauth/apple/response/AppleTokenResponse.kt, infra/src/main/resources/application-external.yml, apis/src/main/resources/static/kakao-login.html
authorizationCode를 활용한 애플 OAuth 인증 전체 플로우 구현, client_secret 생성, refresh token 발급 및 저장, 관련 DTO/서비스/매니저/유틸/설정/프론트 예제 추가 및 변경
카카오 OAuth 인증 리팩토링
apis/src/main/kotlin/org/yapp/apis/auth/manager/KakaoApiManager.kt, apis/src/main/kotlin/org/yapp/apis/auth/strategy/KakaoAuthStrategy.kt
카카오 인증 도우미를 매니저로 대체, 예외 처리 및 의존성 구조 변경
유저/토큰 도메인 및 서비스 구조 변경
domain/src/main/kotlin/org/yapp/domain/user/User.kt, domain/src/main/kotlin/org/yapp/domain/user/UserDomainService.kt, domain/src/main/kotlin/org/yapp/domain/user/vo/UserAuthVO.kt, infra/src/main/kotlin/org/yapp/infra/user/entity/UserEntity.kt, apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt, apis/src/main/kotlin/org/yapp/apis/auth/service/AuthTokenService.kt, apis/src/main/kotlin/org/yapp/apis/auth/service/RefreshTokenService.kt
애플 refresh token 필드 추가 및 갱신, UserAuthVO 도입, 서비스 메서드 시그니처 및 동작 변경, 토큰 서비스 분리 및 역할 재정의
예외 코드 및 에러 코드 표준화
apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt, apis/src/main/kotlin/org/yapp/apis/book/exception/BookErrorCode.kt, apis/src/main/kotlin/org/yapp/apis/book/exception/UserBookErrorCode.kt, apis/src/main/kotlin/org/yapp/apis/readingrecord/exception/ReadingRecordErrorCode.kt, domain/src/main/kotlin/org/yapp/domain/book/exception/BookErrorCode.kt, domain/src/main/kotlin/org/yapp/domain/readingrecord/exception/ReadingRecordErrorCode.kt, domain/src/main/kotlin/org/yapp/domain/token/exception/TokenErrorCode.kt, domain/src/main/kotlin/org/yapp/domain/user/exception/UserErrorCode.kt, domain/src/main/kotlin/org/yapp/domain/userbook/exception/UserBookErrorCode.kt, global-utils/src/main/kotlin/org/yapp/globalutils/exception/CommonErrorCode.kt
모든 에러 코드에 HTTP status prefix를 부여하고 메시지 및 코드 일관성 강화
설정 및 빌드 파일
apis/build.gradle.kts, buildSrc/src/main/kotlin/Dependencies.kt, infra/src/main/resources/application-external.yml, .github/workflows/ci-pr.yml, .github/workflows/dev-ci-cd.yml, .github/workflows/prod-ci-cd.yml
애플 OAuth 및 BouncyCastle 의존성 추가, 애플 인증키 시크릿 처리, 외부 설정값 추가
API 문서 및 어노테이션 현지화
apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthControllerApi.kt
Swagger/OpenAPI 문서 한글화
패키지 및 클래스 리네이밍/정리
apis/src/main/kotlin/org/yapp/apis/auth/util/NicknameGenerator.kt, apis/src/main/kotlin/org/yapp/apis/auth/strategy/AuthStrategyResolver.kt, apis/src/main/kotlin/org/yapp/apis/auth/dto/request/FindOrCreateUserRequest.kt, apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthController.kt
패키지 이동, 클래스/메서드명 정리, 주석 제거 등
불필요/구식 코드 제거
apis/src/main/kotlin/org/yapp/apis/auth/helper/AppleJwtHelper.kt, apis/src/main/kotlin/org/yapp/apis/auth/helper/KakaoApiHelper.kt
기존 JWT 파싱 및 카카오 API 도우미 클래스 제거

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: 토큰 페어 응답
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~70 minutes

Assessment against linked issues

Objective Addressed Explanation
애플 로그인 시 authorizationCode도 idToken과 같이 받도록 변경 (#55)
client_secret을 생성한 후, authorizationCode와 client_secret를 애플 서버로 보내 Access/Refresh 토큰 받기 (#55)
발급받은 Refresh Token을 DB에 저장 (#55)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
에러 코드 표준화 및 코드 문자열 변경 (apis/src/main/kotlin/org/yapp/apis/book/exception/BookErrorCode.kt, ...외 다수) 에러 코드 포맷 일괄 변경은 본 이슈의 목적(애플 로그인 리팩토링)과 직접적 연관이 없습니다.
Swagger/OpenAPI 한글화 (apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthControllerApi.kt) API 문서 현지화는 애플 로그인 인증 플로우 리팩토링과는 무관합니다.
닉네임 생성기 패키지 이동, 주석 제거 등 사소한 리팩토링 (apis/src/main/kotlin/org/yapp/apis/auth/util/NicknameGenerator.kt, ...외) 본 이슈의 범위를 벗어난 코드 정리입니다.

Possibly related PRs

  • refactor: 인증 도메인 리팩토링 #42: 인증 도메인 및 DTO, 서비스 레이어, 예외 처리 리팩토링 등 인증 도메인 구조 변경이 본 PR의 인증 리팩토링과 직접적으로 관련되어 있습니다.

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BOOK-179-refactor/#55

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 82f0a61 and 240ade8.

📒 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: 인증 관련 유틸리티 패키지 재구성 승인

NicknameGeneratorauth.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로의 전환과 NicknameGenerator import 경로 업데이트가 적절합니다.


15-15: 의존성 주입 업데이트가 올바릅니다.

생성자에서 KakaoApiHelperKakaoApiManager로 교체하여 새로운 매니저 클래스를 사용합니다.


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 매니저 구현이 우수합니다.

에러 타입별로 적절한 예외 코드를 매핑하고(HttpClientErrorExceptionINVALID_OAUTH_TOKEN, HttpServerErrorExceptionOAUTH_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 토큰의 핵심 클레임인 subemail을 포함한 구조가 적절합니다. email이 nullable로 처리된 것도 Apple ID 토큰 스펙과 일치합니다.

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: 깔끔한 리팩토링입니다!

AppleJwtHelperAppleIdTokenProcessor로 교체하면서 코드가 더 간결해졌습니다. 명시적인 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로 토큰 관련 작업이 중앙화된 것도 좋은 설계입니다.

private val appleProperties: AppleOauthProperties,
private val resourceLoader: ResourceLoader,
) {
val keyPair: KeyPair = loadKeyPair()
Copy link

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.

Suggested change
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.

Copy link

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 27a4598 and d35387a.

📒 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: 모든 파일에 NicknameGenerator import 경로가 일관되게 변경되었습니다.

검증 결과:

  • 이전 경로(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 호출 변경은 올바르게 반영된 상태입니다.

Copy link

@coderabbitai coderabbitai bot left a 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 환경 워크플로에도 동일 수정 필요

echoprintf 변경 및 공통 스크립트화 제안을 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

📥 Commits

Reviewing files that changed from the base of the PR and between d35387a and 464a354.

📒 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 = httpStatus

Likely 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 설정이 올바르게 구성되어 있습니다. audience URL은 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: 서비스 구조가 잘 설계되었습니다.

RefreshTokenServiceJwtTokenService를 조합하여 토큰 관리의 책임을 명확하게 분리했습니다.


20-33: 토큰 페어 생성 로직이 체계적입니다.

  • 입력 검증을 통한 안전성 확보
  • Access token과 refresh token 순차 생성
  • Refresh token 저장까지 한 번에 처리
  • 명확한 응답 객체 반환

토큰 생성과 저장이 원자적으로 처리되어 일관성이 보장됩니다.


35-38: 토큰 검증 로직이 적절합니다.

검증과 사용자 ID 조회를 순차적으로 수행하여 안전성을 확보했습니다.


40-46: 토큰 삭제 메서드들이 명확합니다.

재발급과 로그아웃에 대한 삭제 로직을 별도 메서드로 분리하여 의도가 명확하고, 향후 다른 로직이 필요할 경우 확장이 용이합니다.


16-19: 서비스 구조가 잘 설계되었습니다.

RefreshTokenServiceJwtTokenService 간의 의존성 분리가 명확하고, 토큰 생성과 관리 책임이 적절하게 분담되어 있습니다.


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 관련 에러들도 적절히 추가되었네요.

Copy link

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 464a354 and fd7d406.

📒 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 전반의 타입 안전성이 향상되었습니다.

Copy link

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between fd7d406 and 7c1171c.

📒 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 인증 관련 서버 측 오류 시나리오가 잘 다루어졌습니다.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Aug 5, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
9.9% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Copy link

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 7c1171c and 3afcb9a.

📒 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 원칙에 따라 설정이 누락된 경우 애플리케이션 시작 시점에 명확한 오류가 발생하게 됩니다.

@move-hoon move-hoon merged commit 5a7528d into develop Aug 5, 2025
3 of 4 checks passed
@move-hoon move-hoon deleted the BOOK-179-refactor/#55 branch August 12, 2025 06:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BOOK-179/refactor] 애플 로그인 시 authorizationCode을 받도록 변경

2 participants