구글 로그인 노트 2: Google Sign-In 남기기
47684 단어 KotlinAuthentication인증logintech
개시하다
Google로 로그인하는 몇 가지 방법이 있습니다.구형 Google Sign-In을 사용하여 구현을 시도한 노트입니다.
✅Google Sign-In
❌ Google Identity Services(g_id_signin)
새 Google 로그인 여기에 →Google 로그인 노트 1: Google Identity Services
❌ Google One Tap 정보
❌ Kotlin(Java) 이외의 설치
주의
구글의 지원은 2023년 3월 31일에 끝난다
참고 자료
컨디션
HTML+JavaScript로 구성된 프런트엔드는 Spring Boot & Kottlin으로 설치
차리다
Spring Boot 프로젝트 제작
spring initializr에서 다음 설정에 따라 프로젝트를 만듭니다.
클라이언트 ID 가져오기
Google Cloud Platform에서 클라이언트 ID 가져오기
아래 설명을 참고하시오.
Get your Google API client ID
다음 내용 설정
승인된 JavaScript 생성 소스 설정
http://localhost과 http://localhost:8080 두 개이루어지다
1. Sign-In With Google 버튼 구성
Front - HTML
resources/templates/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Google Sign-In Demo</title>
</head>
<body>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="CLIENT ID">
<div class="g-signin2" data-onsuccess="onSignIn"></div>
</body>
</html>
google-signin-client_id의 content에서 획득한 클라이언트 ID를 설정합니다.g-signin2의 data-onsuccess 로그인이 완료된 호출 함수 설정 (JavaScritp)버튼 설계 조정 등 자세한 내용은 Building a custom Google Sign-In button 참조
Backend - Kotlin
상기 index."}"을 표시하는 컨트롤러 만들기
RootController.kt
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
@Controller
class RootController {
@GetMapping("/")
fun index(): String {
return "index"
}
}
동작 확인
로그인이 Google에서 실행됩니다.(로그인이 완료된 후 호출 함수가 없어 오류가 발생했습니다)
로그인 화면
2. 로그인 후 호출 완료
Google 로그인이 완료되면 콜백을 생성합니다.
프런트의 JavaScritp에서 다이얼백을 받은 후 처리를 백엔드로 옮깁니다.
Front - HTML
onSignIn auth2.disconnect()에서 로그인 상태를 유지하지 않음googleUser.getAuthResponse()에서 ID 토큰을 가져와 백엔드로 보내기http://localhost:8080/signinSignInControllerhttp://localhost:8080/userinfo로 리디렉션UserInfoController<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Google Sign-In Demo</title>
</head>
<body>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="CLIENT ID">
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<script>
function onSignIn(googleUser) {
console.log('onSignIn.');
var auth2 = gapi.auth2.getAuthInstance();
auth2.disconnect();
// Get ID Token
var id_token = googleUser.getAuthResponse().id_token;
// Send ID Token to Backend
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:8080/signin');
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function() {
if(xhr.readyState == 4 && xhr.status == 200){
// Redirect
window.location.href = 'http://localhost:8080/userinfo';
}else{
console.log('Error');
}
};
xhr.send('credential=' + id_token);
}
</script>
</body>
</html>
Gradle
build.gradle.kts
com.google.api-client:google-api-clientdependencies {
implementation("com.google.api-client:google-api-client:1.31.5")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
Backend - Kotlin
프론트 데스크에서 보낸 ID 영패를 수신하고 검증하다
ID 토큰에 대해서는 OpenID Connect 설명서를 참조하십시오.
ID 토큰의 신뢰성을 확인하려면 Decode(Verify)가 필요합니다.
ID 토큰 Verify 구글 IdToken Verifier 사용
setAudience에 클라이언트 ID 설정ID 토큰의 Verify가 성공하면 사용자 정보를 얻을 수 있습니다.
subject 사용자를 식별하는 IDID 토큰에서 추출한 사용자 정보 세그먼트를 사용자 info 페이지로 저장 및 리디렉션
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier
import com.google.api.client.http.javanet.NetHttpTransport
import com.google.api.client.json.gson.GsonFactory
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.ResponseStatus
import org.springframework.web.bind.annotation.RestController
import javax.servlet.http.HttpServletRequest
@RestController
class SignInController {
@PostMapping("signin")
@ResponseStatus(HttpStatus.OK)
fun signIn(
@RequestParam("credential") credential: String,
request: HttpServletRequest,
) {
// verify ID Token
val verifier = GoogleIdTokenVerifier.Builder(
NetHttpTransport(), GsonFactory.getDefaultInstance()
)
.setAudience(listOf("CLIENT ID"))
.build()
val idToken = verifier.verify(credential) ?: throw Exception()
val payload = idToken.payload
// Get profile information from payload
val session = request.getSession(true)
session.setAttribute("subject", payload.subject)
session.setAttribute("email", payload.email)
session.setAttribute("emailVerified", payload.emailVerified)
session.setAttribute("name", payload["name"])
session.setAttribute("picture", payload["picture"])
session.setAttribute("locale", payload["locale"])
session.setAttribute("family_name", payload["family_name"])
session.setAttribute("given_name", payload["given_name"])
return
}
}
3. 로그인 후 페이지 설치
로그인 사용자 정보를 표시하는 페이지 구현
Front - HTML
resources/templates/userinfo.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<html lang="en">
<head>
<meta charset="UTF-8">
<title>UserInfo</title>
</head>
<body>
<div>subject(User ID):<span th:text="${subject}"></span></div>
<div>email:<span th:text="${email}"></span></div>
<div>emailVerified:<span th:text="${emailVerified}"></span></div>
<div>name:<span th:text="${name}"></span></div>
<div>pictureUrl:<span th:text="${picture}"></span></div>
<div>locale:<span th:text="${locale}"></span></div>
<div>family_name:<span th:text="${family_name}"></span></div>
<div>given_name:<span th:text="${given_name}"></span></div>
<a href="/">Back</a>
</body>
</html>
Backend - Kotlin
세션에서 사용자 정보를 추출하여 프론트 데스크에 넘기다
UserInfoController.kt
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import javax.servlet.http.HttpServletRequest
@Controller
class UserInfoController {
@GetMapping("userinfo")
fun userInfo(
request: HttpServletRequest,
model: Model
): String {
// Get User Info from session
val session = request.getSession(false) ?: throw Exception()
model.addAttribute("subject", session.getAttribute("subject"))
model.addAttribute("email", session.getAttribute("email"))
model.addAttribute("emailVerified", session.getAttribute("emailVerified"))
model.addAttribute("name", session.getAttribute("name"))
model.addAttribute("picture", session.getAttribute("picture"))
model.addAttribute("locale", session.getAttribute("locale"))
model.addAttribute("family_name", session.getAttribute("family_name"))
model.addAttribute("given_name", session.getAttribute("given_name"))
return "userinfo"
}
}
동작 확인
Google로 로그인하면 Backend의 Sign InController가 표시됩니다.signin 실행 후 사용자 info.건너뛰다
UserInfo 화면
수고하셨습니다.
Reference
이 문제에 관하여(구글 로그인 노트 2: Google Sign-In 남기기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/gebo/articles/signinwithgoogle-2-web-legacy텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)