Google OAuth2.0 - Google ID Service

GY·2022년 6월 11일
0

TIL

목록 보기
73/73
post-thumbnail

이전에 카카오 REST API를 사용한 소셜로그인 기능을 구현해본 적이 있고,
구글 로그인은 파이어베이스를 통해서 진행해봤었다.
회사 프로젝트에서 구글 로그인을 진행하게 되어 이번 기회에 정리해보았다.


OAuth란?

자체적으로 로그인/회원가입 서비스를 구현할 경우 사용자로부터 개인정보를 받아 저장/관리해야 하지만,
OAuth 2.0을 사용한다면 대부분의 로그인, 개인정보 관리 책임을 서드파티 애플리케이션에게 위임할 수 있다.

서드파티 애플리케이션?

구글, 페이스북, 깃허브, 카카오등의 소셜로그인 기능을 제공하는 애플리케이션을 말한다.
단, 사용자가 이 서드 파티 서비스에 회원가입이 되어 있어야 로그인이 가능하다는 조건이 있다.(안되어 있는게 이상할 정도로 큰 규모의 서비스들이지만 ㅎㅎ)

시퀀스 다이어그램으로 봤을 때,OAuth 2.0은 보통 이런 과정을 거쳐 진행된다.
업로드중..

내가 구현할 구글 로그인을 기준으로 정리해보면,

  1. Google auth에 접근한다.
  2. 구글은 client ID,와 Redirect URI를 준다.
  3. 이 것을 서버에 전달한다.

Google OAuth2.0

Google Auth2.0, 어떻게 사용할까?

  • 직접 구현하는 방법도 있지만, Google API 클라이언트 라이브러리를 사용하면 OAuth 2.0을 더 간단하게 구현할 수 있다고 한다. 자바스크립트용 라이브러리를 사용해보자.

google-api-javascript-client

  • apikey를 파라미터로 전달해 gapi.client.init함수를 호출해야 한다
gapi.client.init({ 'apiKey':  'YOUR_API_KEY', ...  
}).then(...) 

Issue

원래 구현이 되어 있었지만, 기존 방식은 더 이상 구글이 지원하지 않으므로 새로운 방식으로 다시 만들어야 했다.참고

그리고 자바스크립트용 Google API 클라이언트 라이브러리를 사용하기 위해 살펴봤더니, gapi.auth2 객체는 지원중단된다고 한다. Google API에 액세스할 때는 gapi.client를 계속 사용하면 되는데, 인증/승인 단계는 최신 Google ID 서비스 라이브러리를 사용해야 한다.
나머지 gapi.auth2 모듈과 관련 개체 및 메서드는 더 이상 자동으로 백그라운드에서 로드되지 않으며, 보다 명시적인 Google ID 서비스 라이브러리 개체 및 메서드로 대체되었다.

Google Developers 사이트에서 Google 로그인 자바스크립트 라이브러리에 대한 승인 지원 중단계획을 발표했다. 자세하게는 2023년 3월 31일 라이브러리 사용을 완전히 사용 중지하기 때문에, 2022년 4월 30일부터 새 애플리케이션은 Google ID 서비스 라이브러리를 사용해야 한다고 한다.이미 기존 라이브러리를 사용하고 있었다면, 중단되는 날짜까지 Google ID 서비스 라이브러리로 이전해야한다.이전하는 방법


Google ID 서비스 라이브러리로 변경하는 이유는 기존 라이브러리에 비해 개선된 사항들이 있기 때문이다.


Google ID 서비스란?

Google ID 서비스는 웹 및 Android 앱을 위한 새로운 크로스 플랫폼 로그인 SDK로, 다양한 유형의 사용자 인증 정보를 지원하고 간소화해주는 서비스이다.

사용방법

  1. 구글 사이트에서 간단히 맞춤설정을 마치고 나면, 구글 버튼을 삽입할 수 있는 html코드를 받을 수 있다.
  2. 이 버튼을 사용하면 탭 한 번으로 사용자가 신규가입을 할 수 있다.(원탭 가입)
  3. 세션이 만료된 후에도 사용자가 자동으로 로그인할 수 있다.

Google로 로그인

Google ID 서비스 라이브러리를 통해 구현하고자 하는 것이 인증/사용자 가입/로그인일 경우에,
사용자 인증에 사용되는 email, profile, openid 의 범위의 데이터만 사용하는 경우 구글에서는 Google로 로그인 기능을 권장하고 있다.

Google로 로그인이란?

Google ID 서비스는

이 경우 굉장히 쉽게 기능을 연동할 수 있는데, 그냥 구글 내에서 클라이언트 ID와 리디렉션 URI만 추가해 버튼을 자동으로 생성하고, 코드를 받아 사용하면 된다.

맞춤설정으로 Google 로그인 버튼 HTML 코드 생성하기

Google로 로그인하기 공식문서 페이지

로그인 버튼 렌더링

아래 예시는 모두 공식문서의 예제 코드를 사용했다.

<html>
  <body>
      <script src="https://accounts.google.com/gsi/client" async defer></script>
      <script>
        function handleCredentialResponse(response) {
          console.log("Encoded JWT ID token: " + response.credential);
        }
        window.onload = function () {
          google.accounts.id.initialize({
            client_id: "YOUR_GOOGLE_CLIENT_ID",
            callback: handleCredentialResponse
          });
          google.accounts.id.renderButton(
            document.getElementById("buttonDiv"),
            { theme: "outline", size: "large" }  // customization attributes
          );
          google.accounts.id.prompt(); // also display the One Tap dialog
        }
    </script>
    <div id="buttonDiv"></div> 
  </body>
</html>
  • callback함수로 전달되는 응답값은 base64로 인코딩된 JWT토큰으로, 디코딩해서 사용해야 한다.
    ID token과 이메일이 필요했다.

자격 증명 응답처리

<div id="g_id_onload"
     data-client_id="YOUR_GOOGLE_CLIENT_ID"
     data-callback="handleCredentialResponse">
</div>
<script>
  function handleCredentialResponse(response) {
     // decodeJwtResponse() is a custom function defined by you
     // to decode the credential response.
     const responsePayload = decodeJwtResponse(response.credential);

     console.log("ID: " + responsePayload.sub);
     console.log('Full Name: ' + responsePayload.name);
     console.log('Given Name: ' + responsePayload.given_name);
     console.log('Family Name: ' + responsePayload.family_name);
     console.log("Image URL: " + responsePayload.picture);
     console.log("Email: " + responsePayload.email);
  }
</script>

base64로 인코딩된 JSON 웹 토큰(JWT)문자열은 디코딩했을 때 전체 내용이 다음과 같다.

header
{
  "alg": "RS256",
  "kid": "f05415b13acb9590f70df862765c655f5a7a019e", // JWT signature
  "typ": "JWT"
}
payload
{
  "iss": "https://accounts.google.com", // The JWT's issuer
  "nbf":  161803398874,
  "aud": "314159265-pi.apps.googleusercontent.com", // Your server's client ID
  "sub": "3141592653589793238", // The unique ID of the user's Google Account
  "hd": "gmail.com", // If present, the host domain of the user's GSuite email address
  "email": "elisa.g.beckett@gmail.com", // The user's email address
  "email_verified": true, // true, if Google has verified the email address
  "azp": "314159265-pi.apps.googleusercontent.com",
  "name": "Elisa Beckett",
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/e2718281828459045235360uler",
  "given_name": "Elisa",
  "family_name": "Beckett",
  "iat": 1596474000, // Unix timestamp of the assertion's creation time
  "exp": 1596477600, // Unix timestamp of the assertion's expiration time
  "jti": "abc161803398874def"
}

이렇게 디코딩해 사용하기 위해서는 위 코드에서처럼 decodeJwtResponse()를 사용하도록 공식문서에 소개되어 있는데, JWT라이브러리를 별도로 설치해 사용해주어야 한다.

혹은 html에 스크립트를 삽입하는 방법도 있다.

<script src="https://unpkg.com/jwt-decode/build/jwt-decode.js"></script>

주의

공식문서



Reference

profile
Why?에서 시작해 How를 찾는 과정을 좋아합니다. 그 고민과 성장의 과정을 꾸준히 기록하고자 합니다.

0개의 댓글