Conversation
…inybite-2025/tinybite-server into feature/#28-gogole-apple-login
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough이 PR은 Google 및 Apple 로그인 기능을 구현합니다. GoogleAndAppleSignupRequest의 platform 필드 검증 제약을 Sequence DiagramsequenceDiagram
participant Client
participant AuthService
participant JwtDecoder
participant TokenClaims as Token Claims
Client->>AuthService: getEmailFromIdToken(idToken)
AuthService->>JwtDecoder: decode(idToken)
JwtDecoder-->>AuthService: Jwt object
alt issuer validation
AuthService->>TokenClaims: validate issuer == appleid.apple.com
TokenClaims-->>AuthService: ✓ valid
else issuer invalid
AuthService-->>Client: JwtException → INVALID_TOKEN
end
alt audience validation
AuthService->>TokenClaims: validate audience == appleClientId
TokenClaims-->>AuthService: ✓ valid
else audience invalid
AuthService-->>Client: JwtException → INVALID_TOKEN
end
alt email extraction
AuthService->>TokenClaims: get email from claims
TokenClaims-->>AuthService: email value
AuthService-->>Client: return email
else email missing
AuthService-->>Client: NOT_EXISTS_EMAIL
end
Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/main/resources/application-local.yaml (1)
32-38: 중복된YAML 파일에
중복 블록을 제거하세요:
google: android-id: ${GOOGLE_ANDROID_CLIENT_ID} ios-id: ${GOOGLE_IOS_CLIENT_ID} - -google: - android-id: ${GOOGLE_ANDROID_CLIENT_ID} - ios-id: ${GOOGLE_IOS_CLIENT_ID}src/main/java/ita/tinybite/domain/auth/service/AuthService.java (1)
259-261: 지원되지 않는 LoginType에 대해 예외를 던져야 합니다.현재
APPLE외의LoginType이 전달되면null이 반환됩니다. 이는 호출자에서NullPointerException을 유발할 수 있습니다.} + default -> throw BusinessException.of(AuthErrorCode.INVALID_PLATFORM); } - return null; }또는 switch expression 형태로 변경:
return switch(loginType) { case GOOGLE -> { /* Google logic */ } case APPLE -> { /* Apple logic */ } default -> throw BusinessException.of(AuthErrorCode.INVALID_PLATFORM); };
🧹 Nitpick comments (1)
src/main/java/ita/tinybite/domain/auth/service/AuthService.java (1)
229-231: 예외 로깅 추가 권장일반
Exception을 잡을 때 디버깅을 위해 예외 내용을 로깅하는 것이 좋습니다.} catch (Exception e) { + log.warn("Google ID token verification failed: {}", e.getMessage()); throw BusinessException.of(AuthErrorCode.INVALID_TOKEN); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/ita/tinybite/domain/auth/dto/request/GoogleAndAppleSignupRequest.java(2 hunks)src/main/java/ita/tinybite/domain/auth/service/AuthService.java(3 hunks)src/main/java/ita/tinybite/global/exception/errorcode/AuthErrorCode.java(1 hunks)src/main/resources/application-dev.yaml(1 hunks)src/main/resources/application-local.yaml(1 hunks)src/main/resources/application.yaml(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/resources/application.yaml (1)
src/main/java/ita/tinybite/global/config/AppleConfig.java (2)
Configuration(8-19)Bean(13-18)
🔇 Additional comments (6)
src/main/resources/application-dev.yaml (1)
15-15: LGTM!개발 환경에서
update설정은 적절합니다. 주석으로 환경별 권장 설정을 명시한 것도 좋습니다.src/main/resources/application.yaml (1)
24-29: LGTM!Apple 및 Naver 설정 블록이 올바르게 추가되었습니다.
AppleConfig.java에서apple.client-id를 사용하는 것과 일치합니다.src/main/resources/application-local.yaml (1)
40-42: 주석 처리된 Apple 설정 확인 필요
application.yaml에 정의된apple.client-id가 local 환경에서도 적용됩니다. 로컬 테스트용 별도 Apple Client ID가 필요한 경우 주석을 해제하고 환경 변수를 설정해야 합니다.src/main/java/ita/tinybite/domain/auth/dto/request/GoogleAndAppleSignupRequest.java (1)
16-17: LGTM!
PlatformType은 enum 타입이므로@NotBlank대신@NotNull을 사용하는 것이 올바릅니다.@NotBlank는 String 타입에만 적용됩니다.src/main/java/ita/tinybite/global/exception/errorcode/AuthErrorCode.java (1)
19-21: LGTM!
INVALID_PLATFORM과NOT_EXISTS_EMAIL에러 코드가 적절하게 추가되었습니다. Apple 로그인 시 이메일이 존재하지 않는 경우를 명확히 처리할 수 있습니다.src/main/java/ita/tinybite/domain/auth/service/AuthService.java (1)
52-53: LGTM!
appleClientId필드가@Value를 통해 올바르게 주입됩니다.
| String aud = jwt.getAudience().get(0); | ||
| if (!aud.equals(clientId)) { | ||
| throw BusinessException.of(AuthErrorCode.INVALID_TOKEN); | ||
| } |
There was a problem hiding this comment.
Audience 리스트 비어있는 경우 방어 코드 추가
jwt.getAudience()가 빈 리스트를 반환하면 IndexOutOfBoundsException이 발생할 수 있습니다.
-String aud = jwt.getAudience().get(0);
-if (!aud.equals(clientId)) {
+if (jwt.getAudience().isEmpty() || !jwt.getAudience().get(0).equals(clientId)) {
throw BusinessException.of(AuthErrorCode.INVALID_TOKEN);
}📝 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.
| String aud = jwt.getAudience().get(0); | |
| if (!aud.equals(clientId)) { | |
| throw BusinessException.of(AuthErrorCode.INVALID_TOKEN); | |
| } | |
| if (jwt.getAudience().isEmpty() || !jwt.getAudience().get(0).equals(clientId)) { | |
| throw BusinessException.of(AuthErrorCode.INVALID_TOKEN); | |
| } |
🤖 Prompt for AI Agents
In src/main/java/ita/tinybite/domain/auth/service/AuthService.java around lines
243-246, the code assumes jwt.getAudience() has at least one element and
directly accesses index 0 which can throw IndexOutOfBoundsException; add a
defensive check that jwt.getAudience() is not null and not empty before reading
index 0, and if it is null/empty throw
BusinessException.of(AuthErrorCode.INVALID_TOKEN) (or use the same error path as
other invalid audience cases) so the failure is handled predictably.
| } catch (JwtException e) { | ||
| throw BusinessException.of(AuthErrorCode.INVALID_TOKEN); | ||
| } catch (BusinessException e) { | ||
| throw BusinessException.of(AuthErrorCode.APPLE_LOGIN_ERROR); | ||
| } |
There was a problem hiding this comment.
BusinessException을 다시 잡아서 에러 정보가 손실됩니다.
try 블록 내에서 던진 BusinessException (예: NOT_EXISTS_EMAIL, INVALID_TOKEN)이 catch (BusinessException e)에서 잡혀서 APPLE_LOGIN_ERROR로 덮어씌워집니다. 원래의 구체적인 에러 코드가 손실됩니다.
BusinessException은 그대로 다시 던지세요:
} catch (JwtException e) {
+ log.warn("Apple JWT decoding failed: {}", e.getMessage());
throw BusinessException.of(AuthErrorCode.INVALID_TOKEN);
} catch (BusinessException e) {
- throw BusinessException.of(AuthErrorCode.APPLE_LOGIN_ERROR);
+ throw e;
+} catch (Exception e) {
+ log.error("Apple login error: {}", e.getMessage());
+ throw BusinessException.of(AuthErrorCode.APPLE_LOGIN_ERROR);
}🤖 Prompt for AI Agents
In src/main/java/ita/tinybite/domain/auth/service/AuthService.java around lines
253 to 257, a catch (BusinessException e) block is currently intercepting
BusinessExceptions thrown in the try and replacing them with APPLE_LOGIN_ERROR,
which loses the original error code; remove that catch or change it to rethrow
the original BusinessException (throw e) so specific error codes (e.g.,
NOT_EXISTS_EMAIL, INVALID_TOKEN) are preserved, leaving only the JwtException
mapped to INVALID_TOKEN and any other unexpected exceptions handled separately.
📝 상세 내용
/api/v1/auth/apple/login/api/v1/auth/apple/singup🔗 관련 이슈
Summary by CodeRabbit
새로운 기능
설정
✏️ Tip: You can customize this high-level summary in your review settings.