-
Notifications
You must be signed in to change notification settings - Fork 1
feat: apis,infra google social login (#141) #142
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package org.yapp.apis.auth.manager | ||
|
|
||
| import mu.KotlinLogging | ||
| import org.springframework.stereotype.Component | ||
| import org.springframework.web.client.HttpClientErrorException | ||
| import org.yapp.apis.auth.exception.AuthErrorCode | ||
| import org.yapp.apis.auth.exception.AuthException | ||
| import org.yapp.apis.config.GoogleOauthProperties | ||
| import org.yapp.infra.external.oauth.google.GoogleApi | ||
| import org.yapp.infra.external.oauth.google.response.GoogleUserInfo | ||
|
|
||
| @Component | ||
| class GoogleApiManager( | ||
| private val googleApi: GoogleApi, | ||
| private val googleOauthProperties: GoogleOauthProperties, | ||
| ) { | ||
| private val log = KotlinLogging.logger {} | ||
|
|
||
| fun getUserInfo(accessToken: String): GoogleUserInfo { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial νλΌλ―Έν°μ λν λ¬Έμνλ₯Ό μΆκ°νλ κ²μ κ³ λ €νμΈμ. μ΄μ 리뷰μμ μ κΈ°λ λ€μκ³Ό κ°μ΄ λ¬Έμνλ₯Ό μΆκ°ν μ μμ΅λλ€: +/**
+ * Google OAuth access tokenμ μ¬μ©νμ¬ μ¬μ©μ μ 보λ₯Ό μ‘°νν©λλ€.
+ * @param accessToken Google OAuth 2.0 access token (id_tokenμ΄ μλ)
+ * @return μ‘°νλ Google μ¬μ©μ μ 보
+ * @throws AuthException ν ν°μ΄ μ ν¨νμ§ μκ±°λ Google μλ²μ ν΅μ μ€ν¨ μ
+ */
fun getUserInfo(accessToken: String): GoogleUserInfo {π€ Prompt for AI Agents |
||
| return googleApi.fetchUserInfo(accessToken, googleOauthProperties.url.userInfo) | ||
| .onSuccess { userInfo -> | ||
| log.info { "Successfully fetched Google user info for userId: ${userInfo.id}" } | ||
| } | ||
| .getOrElse { exception -> | ||
| log.error(exception) { "Failed to fetch Google user info" } | ||
|
|
||
| when (exception) { | ||
| is HttpClientErrorException -> throw AuthException( | ||
| AuthErrorCode.INVALID_OAUTH_TOKEN, | ||
| "Invalid Google Access Token.", | ||
| ) | ||
|
|
||
| else -> throw AuthException( | ||
| AuthErrorCode.OAUTH_SERVER_ERROR, | ||
| "Failed to communicate with Google server.", | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| package org.yapp.apis.auth.strategy.signin | ||
|
|
||
| import mu.KotlinLogging | ||
| import org.springframework.stereotype.Component | ||
| import org.yapp.apis.auth.dto.response.UserCreateInfoResponse | ||
| import org.yapp.apis.auth.exception.AuthErrorCode | ||
| import org.yapp.apis.auth.exception.AuthException | ||
| import org.yapp.apis.auth.manager.GoogleApiManager | ||
| import org.yapp.apis.auth.util.NicknameGenerator | ||
| import org.yapp.domain.user.ProviderType | ||
| import org.yapp.infra.external.oauth.google.response.GoogleUserInfo | ||
|
|
||
| @Component | ||
| class GoogleSignInStrategy( | ||
| private val googleApiManager: GoogleApiManager | ||
| ) : SignInStrategy { | ||
|
|
||
| private val log = KotlinLogging.logger {} | ||
|
|
||
| override fun getProviderType(): ProviderType = ProviderType.GOOGLE | ||
|
|
||
| override fun authenticate(credentials: SignInCredentials): UserCreateInfoResponse { | ||
| return try { | ||
| val googleCredentials = validateCredentials(credentials) | ||
| val googleUser = googleApiManager.getUserInfo(googleCredentials.accessToken) | ||
| createUserInfo(googleUser) | ||
| } catch (exception: Exception) { | ||
| log.error("Google authentication failed", exception) | ||
| when (exception) { | ||
| is AuthException -> throw exception | ||
| else -> throw AuthException(AuthErrorCode.FAILED_TO_GET_USER_INFO, exception.message) | ||
| } | ||
| } | ||
| } | ||
|
Comment on lines
+22
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial μμΈ μ²λ¦¬ λ²μ κ²ν κΆμ₯ νμ¬ νμ¬ κ΅¬νλ λ°©μ΄μ μ΄κ³ μ λ΅ ν¨ν΄ 컨ν μ€νΈμμ μμ© κ°λ₯νμ§λ§, νμμ ꡬ체μ μΈ μμΈ νμ μΌλ‘ μΈλΆννλ κ²μ κ³ λ €ν΄λ³΄μΈμ. μ μ λΆμ λꡬμ κ²½κ³ λ₯Ό μ°Έκ³ νμ΅λλ€. π§° Toolsπͺ detekt (1.23.8)[warning] 27-27: The caught exception is too generic. Prefer catching specific exceptions to the case that is currently handled. (detekt.exceptions.TooGenericExceptionCaught) [warning] 27-27: The caught exception is swallowed. The original exception could be lost. (detekt.exceptions.SwallowedException) π€ Prompt for AI Agents |
||
|
|
||
| private fun validateCredentials(credentials: SignInCredentials): GoogleAuthCredentials { | ||
| return credentials as? GoogleAuthCredentials | ||
| ?: throw AuthException( | ||
| AuthErrorCode.INVALID_CREDENTIALS, | ||
| "Credentials must be GoogleAuthCredentials" | ||
| ) | ||
| } | ||
|
|
||
| private fun createUserInfo(googleUser: GoogleUserInfo): UserCreateInfoResponse { | ||
| return UserCreateInfoResponse.of( | ||
| email = googleUser.email ?: ("google_${googleUser.id}@google.com"), | ||
| nickname = NicknameGenerator.generate(), | ||
| profileImageUrl = googleUser.picture, | ||
| providerType = ProviderType.GOOGLE, | ||
| providerId = googleUser.id | ||
| ) | ||
| } | ||
|
Comment on lines
+44
to
+52
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial π§© Analysis chainπ Script executed: find . -type f -name "GoogleSignInStrategy.kt"Repository: YAPP-Github/Reed-Server Length of output: 148 π Script executed: git ls-files | grep -i google | head -20Repository: YAPP-Github/Reed-Server Length of output: 381 π Script executed: git ls-files | grep -i auth | head -30Repository: YAPP-Github/Reed-Server Length of output: 2278 π Script executed: cat apis/src/main/kotlin/org/yapp/apis/auth/dto/response/UserCreateInfoResponse.ktRepository: YAPP-Github/Reed-Server Length of output: 1651 π Script executed: cat infra/src/main/kotlin/org/yapp/infra/external/oauth/google/response/GoogleUserInfo.ktRepository: YAPP-Github/Reed-Server Length of output: 354 π Script executed: cat apis/src/main/kotlin/org/yapp/apis/auth/strategy/signin/GoogleSignInStrategy.ktRepository: YAPP-Github/Reed-Server Length of output: 2142 π Script executed: cat apis/src/main/kotlin/org/yapp/apis/auth/service/UserSignInService.ktRepository: YAPP-Github/Reed-Server Length of output: 1272 π Script executed: rg "email" --type kt apis/src/main/kotlin/org/yapp/apis/auth/ -B 2 -A 2 | head -80Repository: YAPP-Github/Reed-Server Length of output: 93 π Script executed: cat apis/src/main/kotlin/org/yapp/apis/auth/strategy/signin/AppleSignInStrategy.ktRepository: YAPP-Github/Reed-Server Length of output: 1852 π Script executed: cat apis/src/main/kotlin/org/yapp/apis/auth/strategy/signin/KakaoSignInStrategy.ktRepository: YAPP-Github/Reed-Server Length of output: 2136 π Script executed: rg "FindOrCreateUserRequest" --type kotlin -A 20Repository: YAPP-Github/Reed-Server Length of output: 16922 π Script executed: rg "validate.*email|email.*validate" --type kotlin -i -B 2 -A 5Repository: YAPP-Github/Reed-Server Length of output: 1144 π Script executed: rg "sendEmail|send.*mail|mailService" --type kotlin -iRepository: YAPP-Github/Reed-Server Length of output: 49 π Script executed: rg "class User" --type kotlin | grep -v "Response\|Request\|Info\|Strategy"Repository: YAPP-Github/Reed-Server Length of output: 2816 π Script executed: git log --oneline --all -- apis/src/main/kotlin/org/yapp/apis/auth/strategy/signin/GoogleSignInStrategy.kt | head -5Repository: YAPP-Github/Reed-Server Length of output: 129 π Script executed: rg "email" --type kotlin apis/src/main/kotlin/org/yapp/apis/user/ -B 2 -A 2 | head -100Repository: YAPP-Github/Reed-Server Length of output: 4728 π Script executed: cat apis/src/main/kotlin/org/yapp/apis/user/dto/request/FindOrCreateUserRequest.ktRepository: YAPP-Github/Reed-Server Length of output: 2399 π Script executed: cat domain/src/main/kotlin/org/yapp/domain/user/User.ktRepository: YAPP-Github/Reed-Server Length of output: 5536 π Script executed: find . -type f -name "*Test.kt" | grep -i auth | head -10Repository: YAPP-Github/Reed-Server Length of output: 49 π Script executed: rg "getOrDefaultEmail" --type kotlin -B 5 -A 5Repository: YAPP-Github/Reed-Server Length of output: 2616 π Script executed: rg "EmailValidator" --type kotlin -B 3 -A 10Repository: YAPP-Github/Reed-Server Length of output: 3437 π Script executed: find . -type f \( -name "*Test.kt" -o -name "*Tests.kt" \) -exec grep -l "email\|signin\|sign-in" {} \; | head -10Repository: YAPP-Github/Reed-Server Length of output: 49 π Script executed: rg "isValidEmail" --type kotlin -B 5 -A 15Repository: YAPP-Github/Reed-Server Length of output: 2687 π Script executed: rg "EMAIL_PATTERN" --type kotlin -B 2 -A 2Repository: YAPP-Github/Reed-Server Length of output: 1070 π Script executed: find . -type f -name "RegexUtils.kt"Repository: YAPP-Github/Reed-Server Length of output: 137 π Script executed: cat global-utils/src/main/kotlin/org/yapp/globalutils/util/RegexUtils.ktRepository: YAPP-Github/Reed-Server Length of output: 423 π Script executed: rg "providerId.*unique\|unique.*providerId" --type kotlin -iRepository: YAPP-Github/Reed-Server Length of output: 49 π Script executed: rg "findUserByProviderTypeAndProviderId" --type kotlin -B 3 -A 10Repository: YAPP-Github/Reed-Server Length of output: 4431 π Script executed: cat apis/src/main/kotlin/org/yapp/apis/auth/exception/AuthErrorCode.kt | grep -i "email\|user"Repository: YAPP-Github/Reed-Server Length of output: 413 Email fallback handling is working as designed; consider documenting the approach. The synthetic email fallback is intentional and will not cause validation failures. The However, there are design consistency issues worth addressing:
The core design (allowing nullable emails with providerId as the true identifier) is sound. Consider:
π€ Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,14 +7,23 @@ sealed class SignInCredentials { | |||||||||
| } | ||||||||||
|
|
||||||||||
| data class KakaoAuthCredentials( | ||||||||||
| val accessToken: String | ||||||||||
| val accessToken: String, | ||||||||||
| ) : SignInCredentials() { | ||||||||||
| override fun getProviderType(): ProviderType = ProviderType.KAKAO | ||||||||||
| } | ||||||||||
|
|
||||||||||
| data class AppleAuthCredentials( | ||||||||||
| val idToken: String, | ||||||||||
| val authorizationCode: String | ||||||||||
| val authorizationCode: String, | ||||||||||
| ) : SignInCredentials() { | ||||||||||
| override fun getProviderType(): ProviderType = ProviderType.APPLE | ||||||||||
| } | ||||||||||
|
|
||||||||||
| data class GoogleAuthCredentials( | ||||||||||
| val accessToken: String, | ||||||||||
| ) : SignInCredentials() { | ||||||||||
| override fun getProviderType(): ProviderType { | ||||||||||
| return ProviderType.GOOGLE | ||||||||||
| } | ||||||||||
|
Comment on lines
+25
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial ννμ λ°λλ‘ ν΅μΌνλ κ²μ κΆμ₯ν©λλ€.
λ€μ diffλ₯Ό μ μ©νμ¬ μΌκ΄μ±μ κ°μ ν μ μμ΅λλ€: - override fun getProviderType(): ProviderType {
- return ProviderType.GOOGLE
- }
+ override fun getProviderType(): ProviderType = ProviderType.GOOGLEπ Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||
| } | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package org.yapp.apis.config | ||
|
|
||
| import org.springframework.boot.context.properties.ConfigurationProperties | ||
|
|
||
| @ConfigurationProperties(prefix = "oauth.google") | ||
| data class GoogleOauthProperties( | ||
| val url: Url | ||
| ) | ||
|
|
||
| data class Url( | ||
| val userInfo: String | ||
| ) | ||
|
Comment on lines
+10
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
νμ¬
λ€μκ³Ό κ°μ΄ μμ ν μ μμ΅λλ€: @ConfigurationProperties(prefix = "oauth.google")
data class GoogleOauthProperties(
val url: Url
-)
+) {
+ data class Url(
+ val userInfo: String
+ )
+}
-
-data class Url(
- val userInfo: String
-)π€ Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package org.yapp.apis.config | ||
|
|
||
| import org.springframework.boot.context.properties.EnableConfigurationProperties | ||
| import org.springframework.context.annotation.Configuration | ||
|
|
||
| @Configuration | ||
| @EnableConfigurationProperties(GoogleOauthProperties::class) | ||
| class PropertiesConfig |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,9 @@ dependencies { | |
| implementation(Dependencies.Spring.BOOT_STARTER_DATA_REDIS) | ||
| implementation(Dependencies.Spring.KOTLIN_REFLECT) | ||
|
|
||
|
|
||
| implementation(Dependencies.Spring.BOOT_STARTER_OAUTH2_CLIENT) | ||
|
|
||
|
Comment on lines
+11
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial Spring OAuth2 Client μμ‘΄μ± μ¬μ© μ¬λΆ νμΈ μ μ νμ¬ PR μμ λ³Έ μ½λλ§ λ³΄λ©΄ Google μ°λμ |
||
| implementation(Dependencies.RestClient.HTTP_CLIENT5) | ||
| implementation(Dependencies.RestClient.HTTP_CORE5) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,22 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| package org.yapp.infra.external.oauth.google | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.stereotype.Component | ||||||||||||||||||||||||||||||||||||||||||||||
| import org.yapp.infra.external.oauth.google.response.GoogleUserInfo | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| @Component | ||||||||||||||||||||||||||||||||||||||||||||||
| class GoogleApi( | ||||||||||||||||||||||||||||||||||||||||||||||
| private val googleRestClient: GoogleRestClient | ||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||
| companion object { | ||||||||||||||||||||||||||||||||||||||||||||||
| private const val BEARER_PREFIX = "Bearer " | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| fun fetchUserInfo( | ||||||||||||||||||||||||||||||||||||||||||||||
| accessToken: String, | ||||||||||||||||||||||||||||||||||||||||||||||
| userInfoUrl: String, | ||||||||||||||||||||||||||||||||||||||||||||||
| ): Result<GoogleUserInfo> { | ||||||||||||||||||||||||||||||||||||||||||||||
| return runCatching { | ||||||||||||||||||||||||||||||||||||||||||||||
| googleRestClient.getUserInfo(BEARER_PREFIX + accessToken, userInfoUrl) | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+14
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial μ‘μΈμ€ ν ν° κ²μ¦μ μΆκ°νμΈμ.
μλͺ»λ Authorization ν€λλ‘ μΈν API νΈμΆ μ€ν¨λ₯Ό λ°©μ§ν μ μμ΅λλ€. λ€μκ³Ό κ°μ΄ κ²μ¦ λ‘μ§μ μΆκ°ν μ μμ΅λλ€: fun fetchUserInfo(
accessToken: String,
userInfoUrl: String,
): Result<GoogleUserInfo> {
+ require(accessToken.isNotBlank()) { "Access token must not be blank" }
+ val token = if (accessToken.startsWith("Bearer ", ignoreCase = true)) {
+ accessToken
+ } else {
+ BEARER_PREFIX + accessToken
+ }
return runCatching {
- googleRestClient.getUserInfo(BEARER_PREFIX + accessToken, userInfoUrl)
+ googleRestClient.getUserInfo(token, userInfoUrl)
}
}π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||||||||||||||||||||||||||||||||||||||||||
| package org.yapp.infra.external.oauth.google | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.stereotype.Component | ||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.web.client.RestClient | ||||||||||||||||||||||||||||||||||||||||||||||
| import org.yapp.infra.external.oauth.google.response.GoogleUserInfo | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| @Component | ||||||||||||||||||||||||||||||||||||||||||||||
| class GoogleRestClient( | ||||||||||||||||||||||||||||||||||||||||||||||
| builder: RestClient.Builder | ||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||
| private val client = builder.build() | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+7
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial νμμμ μ€μ μ μΆκ°νμΈμ. μΈλΆ API νΈμΆ μ νμμμμ΄ μ€μ λμ΄ μμ§ μμΌλ©΄ μλ΅μ΄ μλ κ²½μ° λ¬΄νμ λκΈ°ν μ μμ΅λλ€. μ°κ²° νμμμκ³Ό μ½κΈ° νμμμμ μ€μ νμ¬ μμ€ν μμ μ±μ ν₯μμν€μΈμ. λ€μκ³Ό κ°μ΄ νμμμμ μ€μ ν μ μμ΅λλ€: +import java.time.Duration
+
@Component
class GoogleRestClient(
builder: RestClient.Builder
) {
- private val client = builder.build()
+ private val client = builder
+ .requestFactory(
+ org.springframework.http.client.SimpleClientHttpRequestFactory().apply {
+ setConnectTimeout(Duration.ofSeconds(5))
+ setReadTimeout(Duration.ofSeconds(10))
+ }
+ )
+ .build()
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| fun getUserInfo( | ||||||||||||||||||||||||||||||||||||||||||||||
| bearerToken: String, | ||||||||||||||||||||||||||||||||||||||||||||||
| url: String, | ||||||||||||||||||||||||||||||||||||||||||||||
| ): GoogleUserInfo { | ||||||||||||||||||||||||||||||||||||||||||||||
| return client.get() | ||||||||||||||||||||||||||||||||||||||||||||||
| .uri(url) | ||||||||||||||||||||||||||||||||||||||||||||||
| .header("Authorization", bearerToken) | ||||||||||||||||||||||||||||||||||||||||||||||
| .retrieve() | ||||||||||||||||||||||||||||||||||||||||||||||
| .body(GoogleUserInfo::class.java) | ||||||||||||||||||||||||||||||||||||||||||||||
| ?: throw IllegalStateException("Google API μλ΅μ΄ null μ λλ€.") | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π§Ή Nitpick | π΅ Trivial μμΈ λ©μμ§λ₯Ό μλ¬ΈμΌλ‘ μμ±νκ±°λ μλ¬ μ½λλ₯Ό μ¬μ©νμΈμ. Line 22μ λ€μκ³Ό κ°μ΄ μμ ν μ μμ΅λλ€: return client.get()
.uri(url)
.header("Authorization", bearerToken)
.retrieve()
.body(GoogleUserInfo::class.java)
- ?: throw IllegalStateException("Google API μλ΅μ΄ null μ
λλ€.")
+ ?: throw IllegalStateException("Google API response body is null")
}π Committable suggestion
Suggested change
π€ Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
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.
π§Ή Nitpick | π΅ Trivial
Google λΆκΈ° λ‘μ§μ κΉλνμ§λ§, ν ν° μλ―Έ(id_token vs access_token)λ₯Ό λͺ νν ν΄ λλ κ²μ΄ μ’μ΅λλ€
ProviderType.GOOGLE -> GoogleAuthCredentials(request.validOauthToken())λ‘ Kakao μ λμΌν ν¨ν΄μΌλ‘ λΆμΈ μ μ μ½κΈ° μ’μ΅λλ€.λ€λ§ νλ‘ νΈμμ νμ¬
id_tokenμ 보λ΄λ ꡬ쑰λΌλ©΄, μ¬κΈ°μ μμ±λλGoogleAuthCredentials.accessTokenμ μ€μ λ‘λ id_token μ κ°λ¦¬ν€κ² λκ³ , μ΄νGoogleApiManagerμμλ μ΄λ₯Ό UserInfo νΈμΆμ© access token μΌλ‘ μ¬μ©νκ² λ©λλ€.μ/λ€λ¨ λͺ¨λμμ μ΄λ€ μ’ λ₯μ ν ν°μ μ£Όκ³ λ°λμ§(access_token / id_token)λ₯Ό μ£Όμμ΄λ λ¬Έμ, νΉμ νλλͺ λ³κ²½μΌλ‘ λͺ νν ν΄ λλ©΄, μ΄ν μ μ§λ³΄μ μ μ€ν΄λ λ²κ·Έλ₯Ό μ€μΌ μ μμ κ² κ°μ΅λλ€.
Also applies to: 55-67
π€ Prompt for AI Agents