Skip to content

[feat] #6 Google/Kakao 소셜 로그인 구현 - #10

Open
kyoooooong wants to merge 8 commits into
developfrom
feat/#6
Open

[feat] #6 Google/Kakao 소셜 로그인 구현#10
kyoooooong wants to merge 8 commits into
developfrom
feat/#6

Conversation

@kyoooooong

@kyoooooong kyoooooong commented Jul 7, 2026

Copy link
Copy Markdown
Member

📌 Related Issue

#️⃣ 요약 설명

  • Google/Kakao OIDC ID 토큰을 검증하고 기존 회원 로그인과 신규 회원가입을 분리한 소셜 로그인 API를 구현했습니다.
  • 검증된 소셜 신원은 30분 동안 Redis에 보관하며, 1회용 registrationKey로 회원가입을 완료합니다.
  • 동시 가입 멱등성, 탈퇴 계정 재가입, UTC 일관성, 입력 및 JWT 설정 검증을 함께 보강했습니다.

📝 작업 내용

  • Google/Kakao provider별 JWK, issuer, audience 기반 OIDC ID 토큰 검증
  • 복수 audience 토큰의 azp 및 필수 sub 검증
  • POST /api/v1/auth/login/{provider} 로그인 API 구현
    • 기존 회원: 200 OK와 Kindl access/refresh token 반환
    • 미가입 회원: 202 Accepted와 30분 유효한 registrationKey 반환
  • POST /api/v1/auth/signup 회원가입 API 구현
  • Controller → Facade → Service → Repository 계층 분리
    • Facade는 외부 토큰 검증과 유스케이스 조합만 담당하며 무트랜잭션으로 유지
    • DB 쓰기는 UserRegistrationService.registerOrReactivate()REQUIRES_NEW로 한정
  • Redis GETDEL 기반 registrationKey 1회 사용 및 30분 TTL 적용
    • ID 토큰 자체는 저장하지 않고 검증된 provider ID/이메일만 임시 보관
  • (provider, provider_id) 유니크 제약과 saveAndFlush() 기반 동시 가입 멱등 처리
    • 충돌 트랜잭션 종료 후 기존 사용자를 재조회하여 동시 요청도 정상 응답
  • soft delete 사용자 재가입 시 기존 행 재활성화
    • 사용자 ID를 유지하고 deleted_at, 닉네임, 이메일 갱신
  • ID 토큰 길이, registrationKey UUID, 닉네임 길이, 약관 동의 입력 검증
  • JWT secret/만료 시간과 roles claim 검증 강화
  • DTO/응답 객체 정적 팩토리 적용 및 user.id!! 제거
  • JVM, Docker, Jackson, Hibernate, MySQL 세션 timezone UTC 통일
  • Actuator 공개 범위를 health endpoint로 제한하고 4xx 로그 민감정보 노출 축소
  • Google/Kakao 브라우저 수동 E2E 전용 Gradle task 추가

👍 동작 확인

  • ./gradlew test --rerun-tasks 성공
  • 전체 51개 테스트 중 49개 통과, 수동 E2E 2개 기본 skip
  • 검증한 주요 시나리오
    • 기존 회원 로그인 / 미가입 회원 registrationKey 발급 / 회원가입
    • 잘못된 provider·ID 토큰·입력값 거부
    • 동일 registrationKey 재사용 차단
    • 서로 다른 키를 사용한 동일 소셜 계정의 순차·동시 가입 멱등성
    • soft delete 후 동일 소셜 계정 재가입 및 기존 ID 유지
    • OIDC audience/azp/sub 검증
    • Redis GETDEL, JWT role, 설정값 검증
    • Actuator health 공개 및 나머지 경로 인증 요구
  • 실제 provider 로그인은 필요할 때 아래 task로 실행할 수 있습니다.
./gradlew googleLoginE2e
./gradlew kakaoLoginE2e

💬 리뷰 요구사항(선택)

  • 트랜잭션 경계
    • Google/Kakao JWK 검증 중 DB 커넥션을 점유하지 않도록 Facade는 무트랜잭션입니다.
    • 유니크 충돌 후 정상 재조회가 가능하도록 실제 INSERT는 별도 REQUIRES_NEW 트랜잭션에서 실행합니다.
  • registrationKey 정책
    • 재사용 공격 방지를 위해 DB 처리 전에 키를 원자적으로 소비합니다.
    • 처리 중 일시적 장애가 발생하면 같은 키로 재시도하지 않고 소셜 로그인부터 다시 진행해야 합니다.
  • 다중 플랫폼 client ID
    • 웹/Android/iOS client ID를 GOOGLE_CLIENT_IDS, KAKAO_CLIENT_IDS 목록으로 받습니다.
    • 복수 audience인 경우 azp도 허용 목록에 포함되어야 합니다.
  • 배포 전 Redis 6.2 이상(GETDEL)과 운영 DB의 (provider, provider_id) 유니크 제약을 확인해야 합니다.
  • 후속 논의 항목
    • 앱-서버 간 OIDC nonce 전달 및 검증 계약
    • 약관 버전/동의 시각 영속화
    • 이메일 컬럼 100자 → 254~255자 확장
    • 운영 Swagger 공개 여부와 로그인 endpoint rate limit

@kyoooooong kyoooooong added the FEAT label Jul 7, 2026
@kyoooooong kyoooooong self-assigned this Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 구글 인증 인가 구현

1 participant