diff --git a/adapters/in-web/src/main/kotlin/com/pokit/auth/model/PrincipalUser.kt b/adapters/in-web/src/main/kotlin/com/pokit/auth/model/PrincipalUser.kt index 36152fa7..6d4693f0 100644 --- a/adapters/in-web/src/main/kotlin/com/pokit/auth/model/PrincipalUser.kt +++ b/adapters/in-web/src/main/kotlin/com/pokit/auth/model/PrincipalUser.kt @@ -11,7 +11,8 @@ data class PrincipalUser( val id: Long, val email: String, val role: Role, - val authPlatform: AuthPlatform + val authPlatform: AuthPlatform, + val sub: String? ) : UserDetails { companion object { fun of(user: User) = @@ -19,7 +20,8 @@ data class PrincipalUser( id = user.id, email = user.email, role = user.role, - authPlatform = user.authPlatform + authPlatform = user.authPlatform, + sub = user.sub ) } @@ -36,4 +38,4 @@ data class PrincipalUser( } } -fun PrincipalUser.toDomain() = User(id = this.id, email = this.email, role = this.role, authPlatform = this.authPlatform) +fun PrincipalUser.toDomain() = User(id = this.id, email = this.email, role = this.role, authPlatform = this.authPlatform, sub = this.sub) diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt index 0c93e3eb..bbf7fe89 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/impl/UserAdapter.kt @@ -19,8 +19,8 @@ class UserAdapter( return savedUser.toDomain() } - override fun loadByEmailAndAuthPlatform(email: String, authPlatform: AuthPlatform) = - userRepository.findByEmailAndAuthPlatformAndDeleted(email, authPlatform, false) + override fun loadBySubAndAuthPlatform(sub: String, authPlatform: AuthPlatform) = + userRepository.findBySubAndAuthPlatformAndDeleted(sub, authPlatform, false) ?.run { toDomain() } override fun loadById(id: Long) = userRepository.findByIdAndDeleted(id, false) @@ -36,4 +36,7 @@ class UserAdapter( userRepository.findByDeleted(false) .map { it.id } + override fun loadByEmailAndAuthPlatform(email: String, authPlatform: AuthPlatform) = + userRepository.findByEmailAndAuthPlatformAndDeleted(email, authPlatform, false) + ?.run { toDomain() } } diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt index abf1c0d8..e4552475 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserEntity.kt @@ -32,7 +32,10 @@ class UserEntity( var deleted: Boolean = false, @Column(name = "is_registered") - var registered: Boolean + var registered: Boolean, + + @Column(name = "sub") + var sub: String? ) : BaseEntity() { fun delete() { this.deleted = true @@ -46,7 +49,8 @@ class UserEntity( role = user.role, nickname = user.nickName, authPlatform = user.authPlatform, - registered = user.registered + registered = user.registered, + sub = user.sub ) } } @@ -57,5 +61,6 @@ fun UserEntity.toDomain() = User( role = this.role, nickName = this.nickname, authPlatform = this.authPlatform, - registered = this.registered + registered = this.registered, + sub = this.sub ) diff --git a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserRepository.kt b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserRepository.kt index c17a9dd3..0ffddccf 100644 --- a/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserRepository.kt +++ b/adapters/out-persistence/src/main/kotlin/com/pokit/out/persistence/user/persist/UserRepository.kt @@ -4,11 +4,13 @@ import com.pokit.token.model.AuthPlatform import org.springframework.data.jpa.repository.JpaRepository interface UserRepository : JpaRepository { - fun findByEmailAndAuthPlatformAndDeleted(email: String,authPlatform: AuthPlatform, deleted: Boolean): UserEntity? + fun findBySubAndAuthPlatformAndDeleted(sub: String, authPlatform: AuthPlatform, deleted: Boolean): UserEntity? fun existsByNickname(nickname: String): Boolean fun findByIdAndDeleted(id: Long, deleted: Boolean): UserEntity? fun findByDeleted(deleted: Boolean): List + + fun findByEmailAndAuthPlatformAndDeleted(email: String, authPlatform: AuthPlatform, deleted: Boolean): UserEntity? } diff --git a/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/user/UserFixture.kt b/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/user/UserFixture.kt index cf07c117..dbb631c9 100644 --- a/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/user/UserFixture.kt +++ b/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/user/UserFixture.kt @@ -9,11 +9,11 @@ import com.pokit.user.model.User class UserFixture { companion object { - fun getUser() = User(1L, "ij@naver.com", Role.USER, authPlatform = AuthPlatform.GOOGLE) + fun getUser() = User(1L, "ij@naver.com", Role.USER, authPlatform = AuthPlatform.GOOGLE, sub = "asdasd") - fun getUserInfo() = UserInfo("ig@naver.com", AuthPlatform.GOOGLE) + fun getUserInfo() = UserInfo("ig@naver.com", AuthPlatform.GOOGLE, sub = "asdasd") - fun getInvalidUser() = User(2L, "dls@naver.com", Role.USER, authPlatform = AuthPlatform.GOOGLE) + fun getInvalidUser() = User(2L, "dls@naver.com", Role.USER, authPlatform = AuthPlatform.GOOGLE, sub = "sub") fun getSignUpRequest() = SignUpRequest("인주니", listOf(InterestType.SPORTS)) } diff --git a/adapters/out-web/src/main/kotlin/com/pokit/auth/common/dto/GoogleUserResponse.kt b/adapters/out-web/src/main/kotlin/com/pokit/auth/common/dto/GoogleUserResponse.kt index 96660de6..26a7b199 100644 --- a/adapters/out-web/src/main/kotlin/com/pokit/auth/common/dto/GoogleUserResponse.kt +++ b/adapters/out-web/src/main/kotlin/com/pokit/auth/common/dto/GoogleUserResponse.kt @@ -1,5 +1,6 @@ package com.pokit.auth.common.dto data class GoogleUserResponse( - val email: String + val email: String, + val sub: String ) diff --git a/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/AppleApiAdapter.kt b/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/AppleApiAdapter.kt index 9502a06c..3a589791 100644 --- a/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/AppleApiAdapter.kt +++ b/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/AppleApiAdapter.kt @@ -25,8 +25,8 @@ class AppleApiAdapter( override fun getUserInfo(idToken: String): UserInfo { val claims = decodeAndVerifyIdToken(idToken) // id token을 통해 사용자 정보 추출 val email = claims["email"] as String - - return UserInfo(email = email, authPlatform = AuthPlatform.APPLE) + val sub = claims["sub"] as String + return UserInfo(email = email, authPlatform = AuthPlatform.APPLE, sub = sub) } override fun revoke(refreshToken: String) { @@ -38,7 +38,7 @@ class AppleApiAdapter( revokeAuth(refreshToken, clientSecret) } - private fun decodeAndVerifyIdToken(idToken: String): Map { + private fun decodeAndVerifyIdToken(idToken: String): Map { val publicKeys = appleFeignClient.getApplePublicKeys() val header = appleTokenParser.parseHeader(idToken) diff --git a/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/GoogleApiAdapter.kt b/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/GoogleApiAdapter.kt index 09ac316f..b2a3f22a 100644 --- a/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/GoogleApiAdapter.kt +++ b/adapters/out-web/src/main/kotlin/com/pokit/auth/impl/GoogleApiAdapter.kt @@ -1,6 +1,5 @@ package com.pokit.auth.impl -import com.pokit.auth.common.property.GoogleProperty import com.pokit.auth.common.support.GoogleFeignClient import com.pokit.auth.port.out.GoogleApiClient import com.pokit.common.exception.ClientValidationException @@ -19,12 +18,13 @@ class GoogleApiAdapter( return UserInfo( email = response.email, - authPlatform = AuthPlatform.GOOGLE + authPlatform = AuthPlatform.GOOGLE, + sub = response.sub ) } override fun revoke(refreshToken: String) { - if(refreshToken.isBlank()) { + if (refreshToken.isBlank()) { return } val revokeResponse = googleFeignClient.revoke(refreshToken) diff --git a/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt b/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt index 3be93345..3cecac09 100644 --- a/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt +++ b/application/src/main/kotlin/com/pokit/auth/port/service/AuthService.kt @@ -37,8 +37,9 @@ class AuthService( AuthPlatform.GOOGLE -> googleApiClient.getUserInfo(request.idToken) AuthPlatform.APPLE -> appleApiClient.getUserInfo(request.idToken) } - - val user = userPort.loadByEmailAndAuthPlatform(userInfo.email, platformType) ?: createUser(userInfo) // 없으면 저장 + val user = userPort.loadBySubAndAuthPlatform(userInfo.sub, platformType) + ?: getUserByEmail(userInfo) // 기존 로그인 유저용, 추후 제거 + ?: createUser(userInfo) // 없으면 저장 val token = tokenProvider.createToken(user.id) @@ -63,7 +64,26 @@ class AuthService( } private fun createUser(userInfo: UserInfo): User { - val user = User(email = userInfo.email, role = Role.USER, authPlatform = userInfo.authPlatform) + val user = User( + email = userInfo.email!!, // 존재하지 않았던 유저면 이메일 항상 존재 + role = Role.USER, + authPlatform = userInfo.authPlatform, + sub = userInfo.sub + ) return userPort.persist(user) } + + private fun getUserByEmail(userInfo: UserInfo): User? { + val userEmail = userInfo.email + + return if(userEmail == null) { + return null + } else { + val user = userPort.loadByEmailAndAuthPlatform(userEmail, userInfo.authPlatform) + user?.let { + it.insertSub(userInfo.sub) + userPort.persist(user) + } + } + } } diff --git a/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt b/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt index a106e4a6..4a9daaa0 100644 --- a/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt +++ b/application/src/main/kotlin/com/pokit/user/port/out/UserPort.kt @@ -6,7 +6,7 @@ import com.pokit.user.model.User interface UserPort { fun persist(user: User): User - fun loadByEmailAndAuthPlatform(email: String, authPlatform: AuthPlatform): User? + fun loadBySubAndAuthPlatform(sub: String, authPlatform: AuthPlatform): User? fun loadById(id: Long): User? @@ -15,4 +15,6 @@ interface UserPort { fun delete(user: User) fun loadAllIds(): List + + fun loadByEmailAndAuthPlatform(email: String, authPlatform: AuthPlatform): User? } diff --git a/domain/src/main/kotlin/com/pokit/user/dto/UserInfo.kt b/domain/src/main/kotlin/com/pokit/user/dto/UserInfo.kt index 91377695..a126c15c 100644 --- a/domain/src/main/kotlin/com/pokit/user/dto/UserInfo.kt +++ b/domain/src/main/kotlin/com/pokit/user/dto/UserInfo.kt @@ -3,6 +3,7 @@ package com.pokit.user.dto import com.pokit.token.model.AuthPlatform data class UserInfo( - val email: String, - val authPlatform: AuthPlatform + var email: String?, + val authPlatform: AuthPlatform, + val sub: String ) diff --git a/domain/src/main/kotlin/com/pokit/user/model/User.kt b/domain/src/main/kotlin/com/pokit/user/model/User.kt index 27fe5fb4..92ed9793 100644 --- a/domain/src/main/kotlin/com/pokit/user/model/User.kt +++ b/domain/src/main/kotlin/com/pokit/user/model/User.kt @@ -11,13 +11,18 @@ data class User( val role: Role, var nickName: String = email, val authPlatform: AuthPlatform, - var registered: Boolean = false + var registered: Boolean = false, + var sub: String? ) { fun register(nickName: String) { this.nickName = nickName this.registered = true } + fun insertSub(sub: String) { + this.sub = sub + } + fun modifyNickname(nickName: String) { this.nickName = nickName }