Skip to content

[fix] SecurityConfig permitAll에 restore/purge-and-register 경로 누락 수정#186

Merged
geunyong16 merged 7 commits into
mainfrom
fix/183-restore-or-purge-on-kakao-relogin
May 11, 2026
Merged

[fix] SecurityConfig permitAll에 restore/purge-and-register 경로 누락 수정#186
geunyong16 merged 7 commits into
mainfrom
fix/183-restore-or-purge-on-kakao-relogin

Conversation

@geunyong16
Copy link
Copy Markdown
Collaborator

@geunyong16 geunyong16 commented May 11, 2026

🔖 관련 GitHub Issue

📝 변경 사항

주요 변경 내용

  • SecurityConfigpermitAll 화이트리스트에 /api/auth/kakao/restore, /api/auth/kakao/purge-and-register 경로 추가

상세 설명

이전 커밋(d6c47e8)에서 탈퇴 후 카카오 재로그인 플로우를 위한 두 엔드포인트가 추가됐지만, SecurityConfigpermitAll 목록에 등록되지 않아 JWT 없이 호출 시 403 Forbidden이 반환되는 문제가 있었습니다.

두 경로 모두 로그인 전 단계(JWT 미보유 상태)에서 앱이 호출하는 인증 엔드포인트이므로, /kakao/login, /kakao/register와 동일하게 permitAll 처리가 필요합니다.

수정 파일: SecurityConfig.java

.requestMatchers(
    "/api/auth/kakao/login",
    "/api/auth/kakao/register",
    "/api/auth/kakao/restore",           // 추가
    "/api/auth/kakao/purge-and-register", // 추가
    "/api/auth/refresh",
    "/api/auth/dev/login"
).permitAll()

📸 스크린샷 (선택사항)

스크린샷 보기

Before

해당 없음 (Security 설정 변경)

After

해당 없음 (Security 설정 변경)

✅ 체크리스트

  • PR 제목이 형식에 맞는가? (유형: 작업 요약)
  • 코드가 정상적으로 빌드되는가?
  • 새로운 기능에 대한 테스트 코드를 작성했는가?
  • 모든 테스트가 통과하는가?
  • 코드 스타일 가이드를 따랐는가?
  • 관련 문서를 업데이트했는가?

🔗 관련 PR


Summary by CodeRabbit

릴리스 노트

  • 신규 기능

    • 탈퇴 계정 복구 기능 추가
    • 탈퇴 계정 완전삭제 후 재가입 기능 추가
    • Kakao 로그인 시 탈퇴 계정 정보 반환 지원
  • 문서

    • 인증 API 명세서 업데이트 - 탈퇴 계정 복구 및 재가입 엔드포인트 추가, 로그인 응답 스키마 개선

Review Change Stack

geunyong16 added 5 commits May 5, 2026 18:21
User 엔티티에 추가된 @Version 필드에 대응하는 DB 마이그레이션 누락으로
모든 API 요청이 500 Internal Server Error를 반환하는 문제 해결.

Closes #181
JPA @Version 필드는 낙관적 잠금을 위해 항상 non-null이어야 하므로
NOT NULL 제약 조건을 추가. DEFAULT 0이 설정되어 있어 기존 행은
안전하게 0으로 초기화됨.

CodeRabbit 리뷰 반영.
- POST /api/auth/kakao/login 응답 변경: 탈퇴 계정 발견 시 예외 대신
  status=WITHDRAWN_PENDING 페이로드 반환하여 클라이언트가 사용자 선택 안내 가능
- POST /api/auth/kakao/restore 신규: User.deletedAt=null로 복구 (탈퇴 취소).
  사업장/계약/근무기록은 다른 사용자 데이터 일관성 보호 위해 자동 복구 안 함
- POST /api/auth/kakao/purge-and-register 신규: 30일 스케줄러와 동일 경로
  (UserHardDeleteService.hardDeleteUser)로 영구 삭제 후 신규 가입
- UserWithdrawService.cleanupCommonData에서 UserSettings 삭제 제거 →
  복구 시 사용자 알림 설정 그대로 유지. 30일 hard delete 시점에 정리됨
- KakaoLoginResult를 평탄 구조로 재설계: status + accessToken/refreshToken/userId/name/userType
  를 top-level에 두어 기존 클라이언트(data.accessToken 등)와 호환 유지. 탈퇴 케이스는
  status=WITHDRAWN_PENDING + withdrawnAccount만 채움.
- purgeAndRegisterWithKakao에 @transactional 추가하여 hardDelete + register를 하나의
  트랜잭션으로 묶음. register 실패 시 hardDelete도 함께 롤백되어 데이터 영구 손실 방지.
- hardDeleteUser 직후 userRepository.flush() 명시 호출. JPA 기본 flush 순서(INSERT→DELETE)
  로 인한 unique kakao_id 제약 충돌을 회피.
- AuthServiceTest: 평탄 응답 접근 방식으로 수정, hardDelete→flush→register 호출 순서 검증,
  register 실패 시 예외 전파 검증 추가.
- docs/API_SPECIFICATION.md: 1.1 카카오 로그인 응답을 평탄 구조로 동기화하고
  1.5 탈퇴 계정 복구, 1.6 완전삭제 후 재가입 항목 신규 추가.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 11, 2026

Warning

Rate limit exceeded

@geunyong16 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 20 minutes and 37 seconds before requesting another review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 140be75f-bf5a-442d-8384-db65f451ea4b

📥 Commits

Reviewing files that changed from the base of the PR and between 0f6f448 and e9acd6d.

📒 Files selected for processing (3)
  • src/main/java/com/example/paycheck/common/exception/ErrorCode.java
  • src/main/java/com/example/paycheck/domain/auth/service/AuthService.java
  • src/main/java/com/example/paycheck/domain/user/scheduler/UserHardDeleteScheduler.java

Walkthrough

Kakao 인증 흐름을 탈퇴 계정 지원으로 확장하고 계정 복구/재가입 기능을 구현하는 변경사항입니다. 로그인 시 탈퇴 계정은 WITHDRAWN_PENDING 상태로 응답하며, 새로운 복구 및 완전삭제 후 재가입 엔드포인트를 통해 사용자가 계정을 복구하거나 새로 가입할 수 있게 됩니다.

Changes

탈퇴 계정 Kakao 인증 흐름

Layer / File(s) Summary
응답 데이터 모델 및 DTO
src/main/java/com/example/paycheck/domain/auth/dto/AuthDto.java
KakaoLoginResult DTO를 추가하여 status (LOGGED_IN 또는 WITHDRAWN_PENDING), 토큰, 사용자 정보, 탈퇴 계정 정보를 포함한 응답 구조 정의. WithdrawnAccountInfo 중첩 DTO로 탈퇴 계정 상세 정보 (이름, 사용자 타입, 탈퇴 시간, 프로필 이미지) 지원.
User 엔티티 및 DB 마이그레이션
src/main/java/com/example/paycheck/domain/user/entity/User.java, src/main/resources/db/migration/V20260505__Add_version_column_to_users.sql
User.restore() 메서드를 추가하여 탈퇴 상태(deletedAt)를 해제. DB 마이그레이션으로 users 테이블에 JPA 낙관적 락용 version 컬럼 추가.
에러 코드
src/main/java/com/example/paycheck/common/exception/ErrorCode.java
탈퇴하지 않은 계정이 복구를 시도할 때 반환하는 USER_NOT_WITHDRAWN 에러 코드 추가.
AuthService 인증 로직
src/main/java/com/example/paycheck/domain/auth/service/AuthService.java
loginWithKakao를 수정하여 탈퇴 계정도 WITHDRAWN_PENDING 응답으로 처리. buildLoginResponse(User user) 헬퍼로 공통 토큰/응답 생성 로직 분리. restoreWithKakao(String) 메서드로 탈퇴 계정 검증 및 복구. purgeAndRegisterWithKakao(...) 메서드로 탈퇴 계정 hard-delete 후 재가입 처리. registerWithKakaoInternal(...) 메서드로 등록 로직 재사용.
AuthController 엔드포인트
src/main/java/com/example/paycheck/api/auth/AuthController.java
/kakao/login 응답 타입을 ApiResponse<AuthDto.KakaoLoginResult>로 변경. 새로운 POST /api/auth/kakao/restorePOST /api/auth/kakao/purge-and-register 엔드포인트 추가.
UserWithdrawService 정리
src/main/java/com/example/paycheck/domain/user/service/UserWithdrawService.java
탈퇴 중 UserSettings 삭제를 제거하여 30일 복구 기간 동안 사용자 설정 보존. 나중 hard-delete 단계에서만 삭제되도록 변경.
보안 설정 업데이트
src/main/java/com/example/paycheck/global/security/SecurityConfig.java
새로운 restore 및 purge-and-register 엔드포인트를 Spring Security permitAll 화이트리스트에 추가하여 비인증 사용자 접근 허용.
API 문서 업데이트
docs/API_SPECIFICATION.md
Kakao 로그인(1.1) 설명을 WITHDRAWN_PENDING 동작으로 갱신. 새로운 1.5 탈퇴 계정 복구 및 1.6 완전삭제 후 재가입 엔드포인트 추가. 각 엔드포인트의 요청/응답/오류 예시 JSON 포함.
AuthService 테스트
src/test/java/com/example/paycheck/domain/auth/service/AuthServiceTest.java
Kakao 로그인 성공 테스트를 KakaoLoginResult 구조에 맞게 갱신. 탈퇴 계정 로그인 시 WITHDRAWN_PENDING 반환 검증. 복구 성공/실패, 완전삭제 후 재가입 성공/실패/활성 계정 거부 테스트 케이스 추가.
UserWithdrawService 테스트 수정
src/test/java/com/example/paycheck/domain/user/service/UserWithdrawServiceTest.java
UserSettings 삭제 검증 제거. 테스트 설명 및 주석을 UserSettings 보존 의도에 맞게 업데이트.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning 원본 변경 요약에 따르면 SecurityConfig 외에도 AuthController, AuthDto, AuthService, User, UserWithdrawService, ErrorCode, 테스트 코드, SQL 마이그레이션 등 많은 파일이 수정되었으나, PR 제목과 설명은 SecurityConfig 변경만을 언급합니다. 실제 PR의 범위가 명시된 목표보다 훨씬 넓습니다. PR이 실제로 포함하는 모든 변경 사항(새 엔드포인트, 탈퇴 계정 복구 로직, DTO 구조 변경, 테스트 등)을 설명에 명시하거나, 범위를 SecurityConfig 변경으로 제한해야 합니다.
Docstring Coverage ⚠️ Warning Docstring coverage is 21.88% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed PR 타이틀은 SecurityConfig의 permitAll에 restore/purge-and-register 경로를 추가하는 주요 변경사항을 명확하게 설명하고 있습니다.
Description check ✅ Passed PR 설명은 템플릿의 대부분 섹션(관련 Issue, 주요 변경 내용, 상세 설명, 체크리스트)을 포함하고 있으며, 문제 상황과 해결 방안을 구체적으로 설명했습니다.
Linked Issues check ✅ Passed PR의 코드 변경(SecurityConfig에 두 경로 추가)이 이슈 #185의 요구사항(permitAll에 /api/auth/kakao/restore와 /api/auth/kakao/purge-and-register 경로 추가)을 정확히 충족합니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/183-restore-or-purge-on-kakao-relogin

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
src/main/java/com/example/paycheck/domain/auth/service/AuthService.java (1)

108-120: ⚡ Quick win

내부 헬퍼를 public API에서 분리해주세요.

buildLoginResponse가 public 서비스 메서드 사이에 들어가 있고, registerWithKakaoInternal은 중복 검사/OAuth 검증이 선행된다는 전제를 가진 내부용 로직인데 public으로 열려 있습니다. helper들은 private 섹션으로 내리고 registerWithKakaoInternal 가시성도 줄이는 편이 안전합니다.

♻️ 최소 변경 예시
-    `@Transactional`
-    public AuthDto.LoginResponse registerWithKakaoInternal(
+    private AuthDto.LoginResponse registerWithKakaoInternal(
             AuthDto.KakaoRegisterRequest request,
             KakaoUserInfo userInfo) {

As per coding guidelines, "In Java services, organize imports, class declaration, field declarations, constructors, public methods, and private methods in that order".

Also applies to: 264-273

🤖 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/example/paycheck/domain/auth/service/AuthService.java`
around lines 108 - 120, The helper buildLoginResponse should be moved into the
private methods section and declared private; likewise reduce the visibility of
registerWithKakaoInternal from public to private (or package-private) so
internal-only logic isn't exposed as a public API; reorder the class so public
methods come before private helpers per the Java service organization guideline
and apply the same change for any other internal helper methods in this class
(move them into the private section and adjust visibility).
🤖 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/example/paycheck/domain/auth/service/AuthService.java`:
- Around line 132-150: The restore paths currently only check user.isDeleted();
add a shared helper (e.g., validateRestorable(User user)) that verifies deleted
flag AND that deletedAt is within the 30-day cutoff (compare user.getDeletedAt()
to Instant.now().minus(30, ChronoUnit.DAYS)), and call it from restoreWithKakao
(and the other restore method that currently uses isDeleted()) before calling
user.restore(); keep existing error types
(BadRequestException/ErrorCode.USER_NOT_WITHDRAWN or create a new ErrorCode like
USER_RECOVERY_WINDOW_EXPIRED) and return buildLoginResponse(user) on success.

---

Nitpick comments:
In `@src/main/java/com/example/paycheck/domain/auth/service/AuthService.java`:
- Around line 108-120: The helper buildLoginResponse should be moved into the
private methods section and declared private; likewise reduce the visibility of
registerWithKakaoInternal from public to private (or package-private) so
internal-only logic isn't exposed as a public API; reorder the class so public
methods come before private helpers per the Java service organization guideline
and apply the same change for any other internal helper methods in this class
(move them into the private section and adjust visibility).
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6a81c1ec-ee68-40b2-8501-2ea655d31885

📥 Commits

Reviewing files that changed from the base of the PR and between e4a621e and 0f6f448.

📒 Files selected for processing (11)
  • docs/API_SPECIFICATION.md
  • src/main/java/com/example/paycheck/api/auth/AuthController.java
  • src/main/java/com/example/paycheck/common/exception/ErrorCode.java
  • src/main/java/com/example/paycheck/domain/auth/dto/AuthDto.java
  • src/main/java/com/example/paycheck/domain/auth/service/AuthService.java
  • src/main/java/com/example/paycheck/domain/user/entity/User.java
  • src/main/java/com/example/paycheck/domain/user/service/UserWithdrawService.java
  • src/main/java/com/example/paycheck/global/security/SecurityConfig.java
  • src/main/resources/db/migration/V20260505__Add_version_column_to_users.sql
  • src/test/java/com/example/paycheck/domain/auth/service/AuthServiceTest.java
  • src/test/java/com/example/paycheck/domain/user/service/UserWithdrawServiceTest.java

- UserHardDeleteScheduler.RETENTION_DAYS를 public으로 공개 (SSOT)
- ErrorCode에 RECOVERY_PERIOD_EXPIRED 추가
- AuthService에 assertWithinRecoveryPeriod() helper 추가
- restoreWithKakao, purgeAndRegisterWithKakao 양쪽에 30일 컷오프 검사 적용
  (스케줄러 지연 시에도 만료 계정 복구/재가입 차단)
- ErrorCode.java: RECOVERY_PERIOD_EXPIRED 유지
- AuthService.java: assertWithinRecoveryPeriod helper 및 호출부 유지
@geunyong16 geunyong16 force-pushed the fix/183-restore-or-purge-on-kakao-relogin branch from bb2a91a to e9acd6d Compare May 11, 2026 11:14
@geunyong16 geunyong16 merged commit 5bff0ce into main May 11, 2026
2 checks passed
@geunyong16 geunyong16 deleted the fix/183-restore-or-purge-on-kakao-relogin branch May 11, 2026 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] /api/auth/kakao/restore, /kakao/purge-and-register 가 SecurityConfig permitAll에 누락되어 403 반환

1 participant