구글 로그인 추가
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
package kr.co.vividnext.sodalive.member.social
|
||||
|
||||
import kr.co.vividnext.sodalive.member.login.LoginResponse
|
||||
|
||||
data class SocialLoginResponse(
|
||||
val memberId: Long,
|
||||
val marketingPid: String?,
|
||||
val loginResponse: LoginResponse
|
||||
)
|
@@ -0,0 +1,54 @@
|
||||
package kr.co.vividnext.sodalive.member.social.google
|
||||
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.jwt.TokenProvider
|
||||
import kr.co.vividnext.sodalive.member.MemberAdapter
|
||||
import kr.co.vividnext.sodalive.member.MemberService
|
||||
import kr.co.vividnext.sodalive.member.login.LoginResponse
|
||||
import kr.co.vividnext.sodalive.member.social.SocialLoginResponse
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.security.core.context.SecurityContextHolder
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class GoogleAuthService(
|
||||
private val googleService: GoogleService,
|
||||
private val memberService: MemberService,
|
||||
private val tokenProvider: TokenProvider,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val cloudFrontHost: String
|
||||
) {
|
||||
fun authenticate(idToken: String, container: String, marketingPid: String?): SocialLoginResponse {
|
||||
val googleUserInfo = googleService.getUserInfo(idToken)
|
||||
?: throw SodaException("구글 로그인을 하지 못했습니다. 다시 시도해 주세요")
|
||||
val member = memberService.findOrRegister(googleUserInfo, container, marketingPid)
|
||||
val principal = MemberAdapter(member)
|
||||
val authToken = GoogleAuthenticationToken(idToken, principal.authorities)
|
||||
authToken.setPrincipal(principal)
|
||||
SecurityContextHolder.getContext().authentication = authToken
|
||||
|
||||
val jwt = tokenProvider.createToken(
|
||||
authentication = authToken,
|
||||
memberId = member.id!!
|
||||
)
|
||||
|
||||
val loginResponse = LoginResponse(
|
||||
userId = member.id!!,
|
||||
token = jwt,
|
||||
nickname = member.nickname,
|
||||
email = member.email,
|
||||
profileImage = if (member.profileImage != null) {
|
||||
"$cloudFrontHost/${member.profileImage}"
|
||||
} else {
|
||||
"$cloudFrontHost/profile/default-profile.png"
|
||||
}
|
||||
)
|
||||
|
||||
return SocialLoginResponse(
|
||||
memberId = member.id!!,
|
||||
marketingPid = marketingPid,
|
||||
loginResponse = loginResponse
|
||||
)
|
||||
}
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package kr.co.vividnext.sodalive.member.social.google
|
||||
|
||||
import org.springframework.security.authentication.AbstractAuthenticationToken
|
||||
import org.springframework.security.core.GrantedAuthority
|
||||
|
||||
class GoogleAuthenticationToken(
|
||||
private val idToken: String,
|
||||
authorities: Collection<GrantedAuthority>? = null
|
||||
) : AbstractAuthenticationToken(authorities) {
|
||||
private var principal: Any? = null
|
||||
init { isAuthenticated = authorities != null }
|
||||
override fun getCredentials(): Any = idToken
|
||||
override fun getPrincipal(): Any? = principal
|
||||
fun setPrincipal(principal: Any) { this.principal = principal }
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package kr.co.vividnext.sodalive.member.social.google
|
||||
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier
|
||||
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
|
||||
import com.google.api.client.json.gson.GsonFactory
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
class GoogleService(
|
||||
@Value("\${google.web-client-id}")
|
||||
private val googleWebClientId: String
|
||||
) {
|
||||
private val transport = GoogleNetHttpTransport.newTrustedTransport()
|
||||
private val jsonFactory = GsonFactory.getDefaultInstance()
|
||||
private val clientIds = listOf(googleWebClientId)
|
||||
|
||||
fun getUserInfo(idToken: String): GoogleUserInfo? {
|
||||
val verifier = GoogleIdTokenVerifier.Builder(transport, jsonFactory)
|
||||
.setAudience(clientIds)
|
||||
.setIssuers(listOf("accounts.google.com", "https://accounts.google.com"))
|
||||
.build()
|
||||
|
||||
return try {
|
||||
val token = verifier.verify(idToken)
|
||||
|
||||
if (token != null) {
|
||||
val payload = token.payload
|
||||
val email = payload.email ?: throw SodaException("이메일 제공에 동의하셔야 서비스 이용이 가능합니다.")
|
||||
|
||||
GoogleUserInfo(
|
||||
sub = payload.subject,
|
||||
email = email,
|
||||
name = payload["name"] as? String
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package kr.co.vividnext.sodalive.member.social.google
|
||||
|
||||
data class GoogleUserInfo(
|
||||
val sub: String,
|
||||
val email: String,
|
||||
val name: String?
|
||||
)
|
Reference in New Issue
Block a user