Skip to content

#13 - 카카오, 애플 소셜로그인 구현 #25

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

Merged
merged 8 commits into from
Jul 13, 2024

Conversation

sectionr0
Copy link
Contributor

1. 🔗 관련 이슈

2. 📄 구현한 내용 또는 수정한 내용

  • gradle 설정 추가 (kotlin noarg, jpa, kotest, mockk, jjwt)
  • entity 일부 수정 (group이 예약어라서 수정, OneToMany 주석처리 -> ManyToOne 으로 변경해보면 좋을 것 같아요!)
  • Apple 로그인 설정 (유저정보, 탈퇴)
  • Kakao 로그인 설정 (유저정보, 탈퇴)

3. 🙌 추가적으로 알리고 싶은 내용

  • yml 파일이 서브모듈에 있어서 빌드 오류 날 것 같아요..ㅠㅠ

4. 🙄 TODO / 고민하고 있는 것들

  • 이게 빨리 된다면,, 바로 시큐리티랑 jwt, 회원가입 부분 만들게요!
  • 이슈가 여러개일땐, PR 제목을 어떻게 정하면 좋을까요??

5. ✅ 배포 Checklist

  • SecretKey 를 업데이트 해주세요
  • 본인을 Assign 해주세요.
  • 본인을 제외한 백엔드 개발자를 리뷰어로 지정해주세요.

- gradle에 noarg, jpa 설정
- core, infrastruce 간의 모듈 방향 조정
- group이 예약어기 때문에, groupNumber로 변경
- VoteJpaEntity에 OneToMany 부분 수정 (Todo)
- Social domain에 socialRefreshToken 추가
JpaAuditingConfig, OpenFeignConfig 설정
- SocialAuthService 인터페이스, SocialAuthServiceFactory 컴포넌트 추가(전략 패턴 이용)
- 카카오 소셜 로그인 추가
- SocialType에 None 추가 (어드민용)
- kotest+mockk gradle 추가
- SocialAuthServiceFactoryTest 추가
@sectionr0 sectionr0 added 🌱기능🌱 새로운 기능을 추가해요 ! 🔥리뷰 기다리는 중🔥 PR을 올리고 코드리뷰를 기다리고 있는 상태입니다. 🥭망고🥭 labels Jul 11, 2024
@sectionr0 sectionr0 requested a review from kpeel5839 July 11, 2024 16:24
@sectionr0 sectionr0 self-assigned this Jul 11, 2024
Copy link
Contributor

@kpeel5839 kpeel5839 left a comment

Choose a reason for hiding this comment

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

이슈가 여러개일땐, PR 제목을 어떻게 정하면 좋을까요??

음 그럴 때에는, #13, 14, 15... 이런 식으로 이슈 번호를 prefix에 써주고, 제목은 좀 포괄적으로 작성하시는거 어떠신가요?

그리고, apple service는 장벽이 굉장히 높네요.. jwt token 미쳤어어어

그리고 코멘트들 남긴 것들은 대부분 의견을 여쭙는거고, 빠른 진행을 위해 Approve 드리도록 하겠습니다.

@Configuration
@EnableJpaAuditing
class JpaAuditingConfig {
}
Copy link
Contributor

Choose a reason for hiding this comment

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

EOF 추가하면 좋을 것 같아요!!


subprojects {
apply(plugin = "java")

apply(plugin = "kotlin")
apply(plugin = "kotlin-spring")
apply(plugin = "kotlin-kapt")
apply(plugin = "kotlin-noarg")
Copy link
Contributor

Choose a reason for hiding this comment

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

이놈짜슥.. 이거였구만

@@ -55,6 +54,9 @@ subprojects {
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("mysql:mysql-connector-java:8.0.32")

// https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk15on
implementation("org.bouncycastle:bcpkix-jdk15on:1.69")
Copy link
Contributor

Choose a reason for hiding this comment

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

오호라 이거는 꼭 추가해야하는 의존성인가요?!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

저걸로 꼭 안해도 되긴하는데 없으면 힘드러요 흑흑

Copy link
Contributor

Choose a reason for hiding this comment

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

그럼 추가해야징~~~

Comment on lines 7 to 17
class CustomErrorDecoder : ErrorDecoder {
override fun decode(methodKey: String, response: Response): Exception {
return when (response.status()) {
400 -> IllegalArgumentException("Bad request from OAuth")
401 -> IllegalArgumentException("OAuth Authentication failed")
404 -> NoSuchElementException("Resource not found from OAuth")
500 -> RuntimeException("Internal server error from OAuth")
else -> RuntimeException("Unknown error occurred from OAuth")
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

여기서 사용되는 ErrorDecoder는 OpenFeign에서만 사용되는것인가요?!

Copy link
Contributor

Choose a reason for hiding this comment

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

import 확인해보니까 feign errordecoder 맞군요

Copy link
Contributor Author

Choose a reason for hiding this comment

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

네 맞아요!

Comment on lines +18 to +31
@Bean
fun errorDecoder(): ErrorDecoder {
return CustomErrorDecoder()
}

@Bean
fun feignMessageConverter(): MappingJackson2HttpMessageConverter {
return MappingJackson2HttpMessageConverter()
}

@Bean
fun restTemplate(messageConverters: List<HttpMessageConverter<*>>): RestTemplate {
return RestTemplateBuilder().additionalMessageConverters(messageConverters).build()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

오호라, errorDecoder이외의 Converter, restTemplate은 꼭 필요한 설정인 것인가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

이전에 로그상의 문제가 생겨서 작성했었는데,, 기억이 가물가물🥲
로그인쪽 다 되면 한 번 확인하고 필요 없다면 제거하겠습니다!

Copy link
Contributor

Choose a reason for hiding this comment

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

근데 사실 뺄 필요는 없어요. 근거가 있는 것인지! 여쭤봤던거에요 호호호호

Comment on lines 6 to 14
@Component
class SocialAuthServiceFactory(
private val services: List<SocialAuthService>
) {
fun getService(socialType: SocialType): SocialAuthService {
return services.find { it.isSupport(socialType) }
?: throw IllegalArgumentException("Unsupported social type: $socialType")
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

아주 멋있는 구조입니다~~
다만, AuthService라고 되어 있으니, Component말고 Service 어노테이션을 붙이는 것도 괜찮아보여요

@@ -0,0 +1,6 @@
package com.wespot.auth.dto

data class OAuthIdAndRefreshToken(
Copy link
Contributor

Choose a reason for hiding this comment

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

AuthLoginRequest와 동일하게 AuthLoginResponse도 괜찮을 것 같아요! 사용목적이 조금 더 잘 드러나지 않나 싶습니다.

Copy link
Contributor Author

@sectionr0 sectionr0 Jul 12, 2024

Choose a reason for hiding this comment

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

해당 dto가 외부(컨트롤러)로 나가지 않은 dto여서 response를 안 붙였는데,, 붙이는게 좋을까요??👀

Copy link
Contributor

Choose a reason for hiding this comment

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

아! 해당 DTO apple, kakao service가 반환하고 있어서 말씀드렸던 것인데, 컨트롤러로 나가지는 않는군요. 사실 And가 붙어서 그랬어요 흑흑 ㅠ

Comment on lines 46 to 53
private fun getAppleId(identityToken: String): String {
val headers = appleJwtParser.parseHeaders(identityToken)
val applePublicKeys = appleClient.getApplePublicKeys()
val publicKey = applePublicKeyGenerator.generatePublicKey(headers, applePublicKeys)
val claims: Claims = Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(identityToken).body

return claims.subject
}
Copy link
Contributor

Choose a reason for hiding this comment

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

이런 식으로 길게 늘어져 있는 스트림 파이프라인은 개행을 넣어주는 것이 가독성이 조금 더 좋다는 생각이 들어요.
기천짱은 어떠신가용?

private fun getAppleId(identityToken: String): String {
    val headers = appleJwtParser.parseHeaders(identityToken)
    val applePublicKeys = appleClient.getApplePublicKeys()
    val publicKey = applePublicKeyGenerator.generatePublicKey(headers, applePublicKeys)
    val claims: Claims = Jwts.parserBuilder()
        .setSigningKey(publicKey)
        .build()
        .parseClaimsJws(identityToken)
        .body

    return claims.subject
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

좋습니당!

Comment on lines 18 to 24
every { kakaoService.isSupport(SocialType.KAKAO) } returns true
every { kakaoService.isSupport(SocialType.APPLE) } returns false
every { kakaoService.isSupport(SocialType.NONE) } returns false

every { appleService.isSupport(SocialType.KAKAO) } returns false
every { appleService.isSupport(SocialType.APPLE) } returns true
every { appleService.isSupport(SocialType.NONE) } returns false
Copy link
Contributor

Choose a reason for hiding this comment

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

도대체 이 every every 는 뭐죠 ㅋㅋㅋㅋㅋ 엄청 좋아보이네요

Copy link
Contributor Author

Choose a reason for hiding this comment

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

kotest 세계관에서 최강입니다.

Copy link
Contributor

Choose a reason for hiding this comment

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

every body is 기천짱

Comment on lines 26 to 46
`when`("Kakao 소셜 타입에 대한 서비스를 요청할 때") {
then("KakaoService를 반환해야 한다") {
val service = factory.getService(SocialType.KAKAO)
service shouldBe kakaoService
}
}

`when`("Apple 소셜 타입에 대한 서비스를 요청할 때") {
then("AppleService를 반환해야 한다") {
val service = factory.getService(SocialType.APPLE)
service shouldBe appleService
}
}

`when`("지원하지 않는 소셜 타입에 대한 서비스를 요청할 때") {
then("IllegalArgumentException을 던져야 한다") {
shouldThrow<IllegalArgumentException> {
factory.getService(SocialType.NONE)
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

테스트 아 주 야 무 집 니 다.
근데, 저희 테스트 한 패키지에다가 몰아서 작성하자고 이야기 나누었던 것 같은데, Core였던가요?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

그거 어디로 정했는지 기억이 안나서ㅜㅜ 일단 core에 했는데 app 쪽으로 옮길까요 흐으음

Copy link
Contributor

Choose a reason for hiding this comment

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

app쪽으로 가시죵!!

Copy link
Contributor Author

@sectionr0 sectionr0 Jul 13, 2024

Choose a reason for hiding this comment

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

현재 app 쪽에 테스트가 잘 안되서,, 다음 pr 때 부터 수정해보고 반영해볼게요!

에러 관련해서는 이따 공유해드리겠습니다!

@sectionr0 sectionr0 merged commit 6440fd5 into develop Jul 13, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🌱기능🌱 새로운 기능을 추가해요 ! 🔥리뷰 기다리는 중🔥 PR을 올리고 코드리뷰를 기다리고 있는 상태입니다.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants