-
Notifications
You must be signed in to change notification settings - Fork 0
#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
Conversation
- gradle에 noarg, jpa 설정 - core, infrastruce 간의 모듈 방향 조정
- group이 예약어기 때문에, groupNumber로 변경 - VoteJpaEntity에 OneToMany 부분 수정 (Todo) - Social domain에 socialRefreshToken 추가
JpaAuditingConfig, OpenFeignConfig 설정
- SocialAuthService 인터페이스, SocialAuthServiceFactory 컴포넌트 추가(전략 패턴 이용)
- 카카오 소셜 로그인 추가 - SocialType에 None 추가 (어드민용)
- kotest+mockk gradle 추가 - SocialAuthServiceFactoryTest 추가
There was a problem hiding this 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 { | ||
} |
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
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") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호라 이거는 꼭 추가해야하는 의존성인가요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저걸로 꼭 안해도 되긴하는데 없으면 힘드러요 흑흑
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그럼 추가해야징~~~
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") | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기서 사용되는 ErrorDecoder는 OpenFeign에서만 사용되는것인가요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import 확인해보니까 feign errordecoder 맞군요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
네 맞아요!
@Bean | ||
fun errorDecoder(): ErrorDecoder { | ||
return CustomErrorDecoder() | ||
} | ||
|
||
@Bean | ||
fun feignMessageConverter(): MappingJackson2HttpMessageConverter { | ||
return MappingJackson2HttpMessageConverter() | ||
} | ||
|
||
@Bean | ||
fun restTemplate(messageConverters: List<HttpMessageConverter<*>>): RestTemplate { | ||
return RestTemplateBuilder().additionalMessageConverters(messageConverters).build() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오호라, errorDecoder이외의 Converter, restTemplate은 꼭 필요한 설정인 것인가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이전에 로그상의 문제가 생겨서 작성했었는데,, 기억이 가물가물🥲
로그인쪽 다 되면 한 번 확인하고 필요 없다면 제거하겠습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
근데 사실 뺄 필요는 없어요. 근거가 있는 것인지! 여쭤봤던거에요 호호호호
@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") | ||
} | ||
} |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AuthLoginRequest와 동일하게 AuthLoginResponse도 괜찮을 것 같아요! 사용목적이 조금 더 잘 드러나지 않나 싶습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
해당 dto가 외부(컨트롤러)로 나가지 않은 dto여서 response를 안 붙였는데,, 붙이는게 좋을까요??👀
There was a problem hiding this comment.
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가 붙어서 그랬어요 흑흑 ㅠ
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 | ||
} |
There was a problem hiding this comment.
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
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
좋습니당!
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
도대체 이 every every 는 뭐죠 ㅋㅋㅋㅋㅋ 엄청 좋아보이네요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kotest 세계관에서 최강입니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
every body is 기천짱
`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) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테스트 아 주 야 무 집 니 다.
근데, 저희 테스트 한 패키지에다가 몰아서 작성하자고 이야기 나누었던 것 같은데, Core였던가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그거 어디로 정했는지 기억이 안나서ㅜㅜ 일단 core에 했는데 app 쪽으로 옮길까요 흐으음
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
app쪽으로 가시죵!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 app 쪽에 테스트가 잘 안되서,, 다음 pr 때 부터 수정해보고 반영해볼게요!
에러 관련해서는 이따 공유해드리겠습니다!
1. 🔗 관련 이슈
2. 📄 구현한 내용 또는 수정한 내용
3. 🙌 추가적으로 알리고 싶은 내용
4. 🙄 TODO / 고민하고 있는 것들
5. ✅ 배포 Checklist