Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 소셜 로그인 구현 #9

Merged
merged 48 commits into from
Jan 12, 2025
Merged

feat: 소셜 로그인 구현 #9

merged 48 commits into from
Jan 12, 2025

Conversation

jwnnoh
Copy link
Member

@jwnnoh jwnnoh commented Jan 5, 2025

✅ PR 유형

어떤 변경 사항이 있었나요?

  • 새로운 기능 추가
  • 버그 수정
  • 리팩토링
  • 코드에 영향을 주지 않는 변경사항(주석, 개행 등등..)
  • 문서 수정
  • 빌드 부분 혹은 패키지 매니저 수정
  • 테스트 코드 추가

✏️ 작업 내용

Caution

상당히 많은 양의 FC가 존재합니다. 죄송하다는 말씀 드립니다..🥺

Note

1월 10일부 모든 모듈에 대한 테스트 코드 작성 완료하였습니다! 🥰


Swagger

image

Test 결과 예시(Persistence-DB 모듈)

image

모듈 분리

Domain

  • 순수 코틀린으로만 작성되어 있는 모듈입니다.
  • Independent 모듈을 제외한 외부 모듈에 대한 의존성을 지니지 않습니다.
  • 의존성 역전을 위해 Port&Adapter 구조를 적용하였습니다.
    • 외부(facade)에서 들어오는 로직은 전부 usecase 인터페이스를 통해 전달됩니다.
    • 이후 service 클래스에서 해당 유스케이스를 구현합니다.
    • 엔티티 변경 및 생성과 같은 경우는 port(out)를 통한 의존성 역전을 통해 구현해주었습니다.
      port-adapter

Independent

  • 모든 모듈에서 공통적으로 쓰이게 되는 모듈입니다.
  • 공통 응답 객체, 예외처리를 위한 코드 정리를 위해 존재합니다.
  • feat: 공통 응답 객체 구현 #4 PR을 참고하시면 더욱 좋습니다.

Infrastructure

  • 외부 인프라에 대한 책임을 지니고 있는 모듈입니다. 현재 Sentry, JPA, Security 등의 하위 모듈들이 적용되어 있습니다.
persistence-db
  • JPA 연동을 위한 모듈입니다.
  • 엔티티 객체가 정의되어 있습니다.
  • JPARepository, 그리고 해당 repository를 인자로 가져와 도메인 모듈의 port의 구현체 역할을 하는 repository 클래스가 구현되어 있습니다.
    repository
security
  • Spring Security 관련 로직에 대한 책임을 지니고 있습니다.
  • JWT 관련 클래스(필터, 토큰 생성, 에러 핸들링) 등이 존재합니다.
  • 소셜 로그인 과정에서 필요한 HTTP 요청에 대한 로직이 존재합니다.
    • KakaoAccessToken, KakaoProfile에 대한 DTO 및 직렬화/역직렬화 로직이 존재합니다.

presentation

  • 게이트웨이, 애플리케이션 실행에 대한 책임을 지니고 있습니다.
  • 컨트롤러에 파사드 패턴을 적용하였습니다.
  • 파사드 클래스는 처리하고자 하는 도메인의 usecase를 인자로 가져와 로직을 처리합니다.
  • 이를 통해 공통되는 로직을 상위 수준에서 간결하게 정리해줍니다.
    facade

멤버 생성 로직 구현

Note

JPA 특성상 Kotlin이 추구하는 방향과 조금 결이 다른 부분이 존재합니다.

  • 멀티모듈을 위해 도메인 <-> 엔티티 클래스를 분리했습니다.
  • 도메인 클래스에서 엔티티를 생성하기 위한 정보를 전달하기 위해 VO 객체를 사용하였습니다.
  • 이후 엔티티 클래스에서 전달받은 VO를 기반으로 엔티티로 매핑한 후, persistence-db 모듈을 통해 엔티티를 저장합니다.
  • 이 때, UUID의 경우 DB에서 자체적으로 생성해주기 때문에 엔티티의 경우 부득이하게 null을 초기값으로 설정해두었습니다.
  • 엔티티를 도메인으로 변환하는 과정은 필연적으로 ID가 존재하기에, !! 어설션을 통해 NotNull을 정의해두었습니다.
        fun toDomain(): Member {
            return Member(
                id = id!!,
                socialId = socialId,
                nickname = nickname,
                email = email,
            )
        }

토큰 생성 로직 변경

토큰 발급 로직에 DI를 적용하였습니다.

  • AS-IS
    AuthFacade 클래스에서 TokenService.kt에 직접적으로 의존하고 있는 상황이었습니다.
  • TO-BE
    SocialUseCase , SecurityPort 포트 인터페이스를 통해 의존성을 역전하였습니다.
    JwtProvider 클래스는 SecurityPort의 구현체입니다.

소셜 로그인

  • socialPort의 구현체인 SecurityClient를 통해 로직을 구현하였습니다.
  • 해당 과정에서 JSON 직렬화/역직렬화가 필요한 부분(토큰, 카카오 프로파일)은 security 모듈 내부에 DTO로 구현하였습니다.
  • 이후 멤버 생성을 위한 값 전달에 대한 책임은 domain 모듈의 KakaoProfile VO 클래스가 담당하도록 하였습니다.

Security 모듈

  • 가독성을 위해 SecurityConfig를 비롯한 여러 클래스에 코틀린 DSL을 적용하였습니다.
    • e.g.) try-catch -> runCatching
    • e.g.) val foo = Foo.add(bar) -> val foo = Foo.apply { bar }

🔗 관련 이슈


💡 추가 사항

  • 이메일이 변경될 수 있는 우려에 따라, 유일한 사용자를 찾는 매개체를 email이 아닌 socialId로 변경하였습니다.
  • 테스트 코드 결과를 PR에서 확인할 수 있도록 워크플로를 추가하였습니다.
image
  • 01.08부로 전역 예외처리 핸들러 구현했습니다!
  • @1winhyun 님이 일본에 계신 관계로 리뷰가 늦어저 해당 시간동안 테스트 코드 작성 시도해보겠습니다~!!

@jwnnoh jwnnoh linked an issue Jan 5, 2025 that may be closed by this pull request
4 tasks
@jwnnoh jwnnoh self-assigned this Jan 5, 2025
@jwnnoh jwnnoh marked this pull request as draft January 5, 2025 09:01
@jwnnoh jwnnoh changed the title Feat: 소셜 로그인 구현 feat: 소셜 로그인 구현 Jan 5, 2025
yechan-kim and others added 24 commits January 7, 2025 01:06
- Spring Application의 BootJar 생성 후 빌드 된 파일을 Dockerfile에 명시된 위치로 이동하도록 변경
- 외부 모듈에서 의존성을 사용할 수 없도록 변경
Jwt 생성 로직, 필터 로직, 필터 예외처리
Copy link

github-actions bot commented Jan 7, 2025

Test Results

16 tests   16 ✅  0s ⏱️
10 suites   0 💤
10 files     0 ❌

Results for commit cee299c.

♻️ This comment has been updated with latest results.

Copy link
Member

@yechan-kim yechan-kim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 정완님!
PR에 설명이 아주 잘 되어 있어서, 많은 궁금증이 해소가 되었네요!
companion을 사용해서 정적 팩토리 메서드를 만드신 부분이 인상이 깊었습니다!
몇 가지 코멘트를 달아두었으니, 확인 부탁드릴게요!

Copy link
Collaborator

@1winhyun 1winhyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다!!
현재까지 질문사항들을 먼저 적어두었고 추가적인 질문사항 빠른 시일내로 올리도록 하겠습니다.

@jwnnoh jwnnoh requested review from 1winhyun and yechan-kim January 9, 2025 15:34
Copy link
Member

@yechan-kim yechan-kim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

테스트 코드가 업데이트되어 추가적으로 의견 남깁니다!
고생 많으셨습니다!

Copy link
Collaborator

@1winhyun 1winhyun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

추가적인 리뷰 남겼습니다. 확인 한번 부탁드립니다!!

단일 표현식, nullable 여뷰, 인덱스 접근자 적용
@jwnnoh jwnnoh merged commit d364128 into main Jan 12, 2025
2 checks passed
@jwnnoh jwnnoh deleted the feat/#5 branch January 12, 2025 14:22
@jwnnoh jwnnoh added the ✅ test 테스트 코드 label Jan 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⚙️ chore 모듈, 빌드, CI/CD 등 ✨ feature 새로운 기능 ♻️ refactor 코드 리팩토링 🎨 style 코드 스타일 변경 ✅ test 테스트 코드
Projects
None yet
Development

Successfully merging this pull request may close these issues.

✨ 소셜 로그인 구현
3 participants