kimyenac
blog
front-end
구글 원탭 로그인 적용 방법 (HTML API, JavaScript API) with React
2023-09-09

사내 서비스에 구글 원탭 로그인 기능을 도입하는 이슈를 진행하게 되었습니다.

공식문서는 나쁘지 않게 되어 있는 편이긴 한데.. 관련 레퍼런스가 많이 없어서 꽤 삽질을 했던 기억에.. 저도 리마인드 할 겸 다른 분들은 저처럼 삽질하지 마시라고 ^^.. ㅎㅎ React를 사용해서 구글 원탭 로그인 기능을 도입하는 방법을 공유드리려고 합니다!





도입 전, 참고사항


클라이언트 아이디 발급과 외 기타 설정을 위해서는. 구글 로그인 후 웹 클라이언트에 접속하여 세팅을 해주셔야 합니다. (세팅을 하는 사람은 개발자가 될 수도 있고, 담당 프로젝트 매니저 PM 이 될 수도 있습니다. 조직에 맞춰서 진행하시면 됩니다.)

구글 원탭 로그인은 한 번 닫으면 (프롬프트 x 버튼 클릭) 2시간, 또 닫으면 하루동안 안 보여집니다. 이때 다시 노출시켜 확인하고 싶다면 g_state 쿠키값과 캐시를 삭제하면 됩니다.




구글 원탭 로그인


구글 원탭 로그인은 구글에서 제공하는 기능으로 HTML API 또는 JavaScript API 로 사용 가능합니다.

각각 사용방식이 다른데, 무엇을 선택하느냐는 각자 스타일로 선택하셔도 될 듯 한데. 만약 프롬프트 위치나 프롬프트가 나타날 때 애니메이션 적용 등 CSS 를 사용하고 싶다면 HTML API 로 적용하는 방법을 선택하셔야 합니다.

해당 글에선 HTML API 와 JavaScript API 사용법 둘 다 공유하도록 하겠습니다.






HTML API 사용법


먼저 HTML API 를 사용하여 구글 원탭 로그인 기능을 적용하는 방법에 대해 서술해보겠습니다. 공식문서 보러가기

먼저 구글 스크립트를 동적으로 추가해줘야 하는데 저는 useEffect 를 사용해서 추가했습니다. 여기서 마운트 검사를 해주는 이유는 스크립트를 먼저 불러오면 load용 element를 제대로 인식하지 못하는 문제가 있어서 동적으로 추가해야 되어 아래와 같이 처리했습니다.


const isMount = useRef(false);

useEffect(() => {
    // 마운트 확인과 서비스 로그인 여부를 확인
    if (isMount.current || isLogin) return;
    isMount.current = true;

    const gscript = document.createElement('script');
    gscript.src = 'https://accounts.google.com/gsi/client'; // 구글에서 제공하는 스크립트
    gscript.async = true;
    document.body.appendChild(gscript);
}, [isLogin]);

그리고 콜백 함수를 구현합니다. 해당 콜백 함수는 data-callback 에 넣을 자바스크립트 ID 토큰 핸들러 함수로서, ID 토큰을 받아서 처리할 수 있는 함수입니다. 보통 여기서 서비스 로그인 api 를 호출하고, id 토큰을 파라미터로 전달하여 백엔드에서 인증을 받아 로그인을 시켜줍니다.

주의할 점은 element 에 콜백함수를 전달할 때 함수의 이름을 전달해야 하고, 해당 함수는 전역함수여야 되기 때문에 window 에 해당 함수를 추가해줘야 합니다.

interface GoogleOneTapSignInCredentialResponse {점
  clientId: string;
  client_id: string;
  select_by: string;
  credential: string;
}

참고 | 콜백함수에서 받는 response 값은 아래와 같습니다.

interface GoogleOneTapSignInCredentialResponse {
  clientId: string;
  client_id: string;
  select_by: string;
  credential: string;
}

마지막으로 HTML 을 로드합니다. (아래는 예제코드입니다.)

<GoogleOneTapContainer>
      <div
        id="g_id_onload"
        data-client_id={발급받은 클라이언트 아이디}
        data-prompt_parent_id="google_one_tap_box"
        data-cancel_on_tap_outside="false"
        data-callback={callbackName} // 위에서 선언한 콜백함수명
      />
      <div id="google_one_tap_box" />
</GoogleOneTapContainer>

커스텀을 위해 제가 위에서 보여드린 예제처럼 컴포넌트를 감싸서 CSS를 적용할 수도 있습니다.

const GoogleOneTapContainer = styled.div`
  position: fixed;
  right: 15px;
  bottom: 10px;
  z-index: 5;

  // 구글 원탭에서 설정된 Element Id
  #credential_picker_container {
    transition: height 1s;
    animation: picker-animation 0.5s linear 0.4s;

    @keyframes picker-animation {
      from {
        opacity: 0;
      }
      to {
        opacity: 1;
      }
    }
  }
`;





JavaScript API 사용법


이제 JavaScript API 를 사용하여 구글 원탭 로그인 기능을 적용하는 방법에 대해 서술해보겠습니다. 공식문서 보러가기

먼저 구글 스크립트를 추가해줘야 하는데 위에서 HTML API 사용법에서 보여드린대로 useEffect 를 사용하여 추가했습니다.


const isMount = useRef(false);

useEffect(() => {
    // 마운트 확인과 서비스 로그인 여부를 확인
    if (isMount.current || isLogin) return;
    isMount.current = true;

    const gscript = document.createElement('script');
    gscript.src = 'https://accounts.google.com/gsi/client'; // 구글에서 제공하는 스크립트
    gscript.async = true;
    document.body.appendChild(gscript);
}, [isLogin]);

그리고 스크립트를 로드하는데, google.accounts.id.initialize 메서드를 사용하여 Google 계정으로 로그인 클라이언트를 초기화해줍니다.
이때 클라이언트 아이디를 전달해주고, callback 에 반환된 ID 토큰을 처리하는 자바스크립트 함수를 전달 혹은 선언합니다.

google.accounts.id.initialize({
    callback: (res: GoogleOneTapSignInCredentialResponse) => {
      mutate({ model: { credential: res.credential } }); // 서비스 로그인 api
    },
    client_id: 발급받은 클라이언트 아이디,
});

참고 | 콜백함수에서 받는 response 값은 아래와 같습니다.

interface GoogleOneTapSignInCredentialResponse {
  clientId: string;
  client_id: string;
  select_by: string;
  credential: string;
}

마지막으로 google.accounts.id.prompt 메서드를 사용하여 프롬프트를 오픈합니다.
여기서 notification 값을 전달받아서 프롬프트 관련 공고(프롬프트를 띄우지 못하는 이유 등)를 콘솔 로그로 남겨 확인할 수도 있습니다.

google.accounts.id.prompt((notification) => {
	console.log('prompt', notification);
});

JavaScript API 를 사용하여 구글 원탭 로그인 도입 - 주요 소스코드 정리
// 구글 스크립트 추가
  useEffect(() => {
    // 마운트 확인과 서비스 로그인 여부를 확인
    if (isMount.current || isLogin) return;
    isMount.current = true;

    const gscript = document.createElement('script');
    gscript.src = 'https://accounts.google.com/gsi/client'; // 구글에서 제공하는 스크립트
    gscript.async = true;
    document.body.appendChild(gscript);

    gscript.onload = () => {
      google.accounts.id.initialize({
        callback: (res: GoogleOneTapSignInCredentialResponse) => {
          mutate({ model: { credential: res.credential } }); // 서비스 로그인 api
        },
        client_id: 발급받은 클라이언트 아이디,
      });

      google.accounts.id.prompt((notification) => {
        console.log('prompt', notification);
      });
    };
  }, [isLogin]);





Reference

https://developers.google.com/identity/gsi/web/guides/overview?hl=ko