fix: 웹 소셜 로그인 시 deviceToken 없이도 로그인 가능하도록 수정 - #328
Conversation
- SocialLoginRequest.deviceToken의 @notblank 제거 (nullable 허용) - acceptLogin 시그니처를 deviceToken → deviceId로 변경하여 JWT에 deviceId 직접 포함 - bindOrCreateDevice가 deviceId를 반환하도록 수정 - WEB 타입은 deviceToken 없이 device 행 생성 후 deviceId를 JWT에 포함 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 Walkthrough개요OAuth2 소셜 로그인 흐름에서 디바이스 토큰 기반 처리를 디바이스 ID 기반 처리로 변경합니다. 변경 사항디바이스 바인딩 및 ID 반환
OAuth2 로그인 흐름 리팩토링
코드 검토 난이도🎯 3 (중간) | ⏱️ ~20분 변경 사항이 여러 파일에 걸쳐 일관되게 적용되었으나, 로직 자체는 명확하며 (디바이스 토큰에서 디바이스 ID로의 전환), 메서드 시그니처 변경이 관련 호출 사이트를 통해 전파되는 중간 규모의 리팩토링입니다. 관련된 가능성 있는 PR
제안 레이블
제안 검토자
시
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/dongsoop/dongsoop/oauth/controller/OAuth2Controller.java`:
- Around line 180-187: The mobile branch of bindOrCreateDevice currently calls
memberDeviceService.bindDeviceWithMemberId and unsubscribeAnonymous even when
deviceToken is null/blank; update bindOrCreateDevice to validate deviceToken for
non-WEB deviceType and immediately reject with a 4xx (e.g., throw a
BadRequest-like exception) when deviceToken is null or blank, while keeping the
WEB branch behavior that normalizes blank to null and calls
createAndBindWebDevice; ensure the check happens before calling
memberDeviceService.bindDeviceWithMemberId and unsubscribeAnonymous to prevent
null-token lookups and subsequent NPEs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 51388974-2fde-448b-ad90-7087ef18427b
📒 Files selected for processing (6)
src/main/java/com/dongsoop/dongsoop/memberdevice/service/MemberDeviceService.javasrc/main/java/com/dongsoop/dongsoop/memberdevice/service/MemberDeviceServiceImpl.javasrc/main/java/com/dongsoop/dongsoop/oauth/controller/OAuth2Controller.javasrc/main/java/com/dongsoop/dongsoop/oauth/dto/SocialLoginRequest.javasrc/main/java/com/dongsoop/dongsoop/oauth/service/OAuth2Service.javasrc/main/java/com/dongsoop/dongsoop/oauth/service/OAuth2ServiceImpl.java
💤 Files with no reviewable changes (1)
- src/main/java/com/dongsoop/dongsoop/oauth/dto/SocialLoginRequest.java
| private Long bindOrCreateDevice(Long memberId, String deviceToken, MemberDeviceType deviceType) { | ||
| if (deviceType == MemberDeviceType.WEB) { | ||
| memberDeviceService.createAndBindWebDevice(memberId, deviceToken); | ||
| } else { | ||
| memberDeviceService.bindDeviceWithMemberId(memberId, deviceToken); | ||
| unsubscribeAnonymous(deviceToken); | ||
| return memberDeviceService.createAndBindWebDevice(memberId, deviceToken); | ||
| } | ||
|
|
||
| Long deviceId = memberDeviceService.bindDeviceWithMemberId(memberId, deviceToken); | ||
| unsubscribeAnonymous(deviceToken); | ||
| return deviceId; |
There was a problem hiding this comment.
모바일 분기에서 deviceToken 누락을 바로 차단해 주세요.
deviceToken이 nullable로 바뀌었는데, non-WEB 요청에도 여기서 그대로 bindDeviceWithMemberId()와 unsubscribeAnonymous()를 호출합니다. 이 상태면 모바일 요청이 null/blank 토큰으로 들어올 때 findByDeviceToken(null)가 WEB의 null-token 행과 충돌하거나 잘못된 기기를 바인딩할 수 있고, 이어서 List.of(deviceToken)에서 NPE도 납니다. WEB은 blank를 null로 정규화하고, MOBILE은 토큰이 비어 있으면 바로 4xx로 막는 쪽이 안전합니다.
예시 수정
private Long bindOrCreateDevice(Long memberId, String deviceToken, MemberDeviceType deviceType) {
if (deviceType == MemberDeviceType.WEB) {
- return memberDeviceService.createAndBindWebDevice(memberId, deviceToken);
+ String normalizedToken = (deviceToken == null || deviceToken.isBlank()) ? null : deviceToken;
+ return memberDeviceService.createAndBindWebDevice(memberId, normalizedToken);
}
+ if (deviceToken == null || deviceToken.isBlank()) {
+ throw new IllegalArgumentException("모바일 로그인에는 deviceToken이 필요합니다.");
+ }
+
Long deviceId = memberDeviceService.bindDeviceWithMemberId(memberId, deviceToken);
unsubscribeAnonymous(deviceToken);
return deviceId;
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/dongsoop/dongsoop/oauth/controller/OAuth2Controller.java`
around lines 180 - 187, The mobile branch of bindOrCreateDevice currently calls
memberDeviceService.bindDeviceWithMemberId and unsubscribeAnonymous even when
deviceToken is null/blank; update bindOrCreateDevice to validate deviceToken for
non-WEB deviceType and immediately reject with a 4xx (e.g., throw a
BadRequest-like exception) when deviceToken is null or blank, while keeping the
WEB branch behavior that normalizes blank to null and calls
createAndBindWebDevice; ensure the check happens before calling
memberDeviceService.bindDeviceWithMemberId and unsubscribeAnonymous to prevent
null-token lookups and subsequent NPEs.
- SocialLoginRequest.deviceToken의 @notblank 제거 (nullable 허용) - WEB 타입은 createAndBindWebDevice로 device 행 생성 후 반환된 deviceId를 JWT에 직접 포함 - 모바일은 기존 resolveDeviceId 흐름 유지 - acceptLoginWithDeviceId 메서드 추가로 WEB 전용 로그인 처리 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
SocialLoginRequest.deviceToken의@NotBlank제거 — 웹은 로그인 전 FCM 토큰이 없으므로 nullable 허용acceptLogin시그니처를String deviceToken→Long deviceId로 변경 — 컨트롤러에서 device 생성 직후 반환된 deviceId를 JWT에 직접 포함bindOrCreateDevice가Long deviceId를 반환하도록 수정OAuth2ServiceImpl의 불필요한resolveDeviceId,MemberDeviceRepository의존성 제거문제
웹 소셜 로그인 시 FCM 토큰(deviceToken)이 없어
@NotBlank검증 실패로 로그인 불가.기존 구조는 deviceToken으로 deviceId를 조회했기 때문에 토큰이 없으면 JWT에 deviceId가 포함되지 않아 블랙리스트 검사도 우회됐음.
동작 방식
deviceToken없이 요청 →createAndBindWebDevice로 device 행 생성(null 토큰) → 반환된 deviceId를 JWT에 포함bindDeviceWithMemberId로 바인딩 → deviceId 반환Test plan
deviceToken없이 요청해도 로그인 성공 확인deviceToken포함 요청 정상 동작 확인🤖 Generated with Claude Code
Summary by CodeRabbit
릴리스 노트