Google 소셜 로그인 Google API 클라이언트 라이브러리 + GoogleIdTokenVerifier 사용하는 방법

Rest API 서버에서 OAuth2.0을 사용하여 소셜 로그인을 구현해야 했습니다.

프론트는 리액트를 사용했기에 SPA방식을 고려해야 했습니다.

 

보통 아래와 같은 흐름으로 구현이 됩니다.

그림상으로는 1~3번 까지는 SPA에서 처리한다음 4번에서 code와 redirect_url을 반환합니다.

 

현재 진행하는 프로젝트에서는 5번의 access_token과 id_token값까지 프론트에서 받은 다음,

access_token을 백엔드 서버에 제공하여 소셜 정보를 받는 과정으로 변경하였습니다.

 

구글 소셜 로그인 API를 구현하는 방식은 아래 블로그에 잘 설명되어 있습니다. (accessToken 값을 제공받는 과정까지 있습니다.)

antdev.tistory.com/68

 

[Google Login API] Google APIs 신규 프로젝트 생성 및 개발환경 구성 (Spring Boot 레퍼런스를 보면서 구현

Spring Boot 환경에서 구글 소셜 로그인 API를 REST 방식으로 구현하기 지난번 카카오 소셜 로그인 API에 이어 ( 1년반이 지나서 ... ) Spring Boot 환경에서 카카오 로그인 API RESTful방식으로 연동하기 -1장).

antdev.tistory.com

💡 API GET 요청으로 구글 유저 정보 얻는 방법

제공받은 토큰값을 이용하여 아래와 같은 URL 형식으로 제공하면 손쉽게 유저정보를 얻을 수 있습니다.
https://www.googleapis.com/oauth2/v2/userinfo/?access_token="{소셜에서 제공받은 토큰값}"

하지만 API 요청을 하지않는 방법을 찾아서 적용한다면, 속도가 올라가지 않을까란 생각에 다른 방법을 찾게 되었습니다. 하지만... (아래에서 계속)

※ API GET요청을 쓴다해도 속도차이가 나지않는 구성 방법이 있다고 합니다. 자세한건, 아래 링크의 위에서 두번째 답변을 참고하시면 될 것 같습니다. (저는 초짜로 봐도 잘 모르겠습니다.. ㅋㅋ)

https://stackoverflow.com/questions/39061310/validate-google-id-token

 

Validate Google Id Token

I'm using ASP.NET Core to serve an API to an Android client. Android signs in as a Google account and passes a JWT, the ID Token, to API as a bearer token. I have the app working, it does pass th...

stackoverflow.com

 

구글링 중 Google API 클라이언트 라이브러리에 있는 GoogleIdTokenVerifier를 사용하면 제공받은 토큰값을 이용해 유저정보를 얻을 수 있습니다. 아래 공식 문서를 베이스로 구글링하여 따라해보았습니다. 

 

developers.google.com/identity/sign-in/android/backend-auth#calling-the-tokeninfo-endpoint

 

Authenticate with a backend server  |  Google Sign-In for Android

If you use Google Sign-In with an app or site that communicates with a backend server, you might need to identify the currently signed-in user on the server. To do so securely, after a user successfully signs in, send the user's ID token to your server usi

developers.google.com

 

1. gradle에서 필요한 라이브러리를 가져옵니다. 

dependencies {
	implementation group: 'com.google.api-client', name: 'google-api-client-jackson2', version: '1.30.10'
	...
    	compile 'com.google.api-client:google-api-client:1.31.2'
}

 

2. 코드를 작성합니다. (코드가 안전하지 않고 더럽습니다 ㅠㅠ 추후 보완하고 수정본을 올리도록 하겠습니다.)

    @Override
    public AuthDto.GoogleProfileRes userInfoGoogle(AccessTokenReq dto) {

        HttpTransport transport = new NetHttpTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

        GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
            .setAudience(Collections.singletonList(GOOGLE_SNS_CLIENT_ID))
            //.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
            .build();
        String userId = null;
        String email = null;
        try {
            GoogleIdToken idToken = verifier.verify(dto.getAccessToken());

            GoogleIdToken.Payload payload = idToken.getPayload();
            userId = payload.getSubject();
            email = payload.getEmail();
        } catch (GeneralSecurityException e) {
            log.warn(e.getLocalizedMessage());
        } catch (IOException e) {
            log.warn(e.getLocalizedMessage());
        }
        return GoogleProfileRes.builder().id(userId).email(email).build();
    }
  • 처음에 GoogleIdTokenVerifier.Builder의 인자에 어떤값을 넣어야 되나 많은 고민을 했습니다. 
  • 아래 스택오버플로우에 저랑 똑같은 궁금증을 가진 개발자가 질문을 올린것이 있습니다.

stackoverflow.com/questions/37172082/android-what-is-transport-and-jsonfactory-in-googleidtokenverifier-builder

 

Android: What is transport and jsonFactory in GoogleIdTokenVerifier.Builder?

in the blow code, whats is transport and jsonFactory ? (I do not understand) https://developers.google.com/identity/sign-in/android/backend-auth#using-a-google-api-client-library import com.googl...

stackoverflow.com

  • 이 답변에 따르면 사용자가 제공 한 전송으로 tokeninfo 엔드 포인트에 요청하고 JSONFactory를 사용하여 응답을 파싱 할 파서를 만드는 GoogleIdTokenVerifier를 반환한다고 합니다.
  • HttpTransPort를 찾아보니 "HTTP 서버와의 통신을 위한 전송을 제공" 한다고 합니다. 결국 서버랑 통신은 하나봅니다. (저는 안하는줄 알았는데, 이런 바보같은 생각을 하다니...) 
  • 즉, 토큰값을 이용하여 서버에 요청을 한 다음, JSONFactory를 사용하여 건네받은 정보를 JSON 형식으로 파싱하는 것 같습니다. 

 

3. 건네주는 페이로드의 키값은 아래와 같습니다. 필요한 정보들만 빼오면 됩니다. (고유한 id값은 위 코드의 getSubject()로 얻으 실 수 있습니다.)

 

 

적용한 프로젝트는 깃허브를 확인 해주세요.

 

 

참조

www.javatips.net/api/ASSISTmentsDirect-master/src/org/assistments/direct/SignInWithGoogle.java

www.javatips.net/api/com.google.api.client.googleapis.auth.oauth2.googleidtokenverifier