dev💻/프론트엔드

[React, Typescript] 구글 로그인

귤랑귤랑 2024. 10. 6. 15:35

Google Identity Services로의 그레이

 
 

2023년 3월 이후, Google Sign-in platform library는 deprecated 되었으며, Google Identity Services library 되었습니다. 기존 사용하던 react-google-login 라이브러리를 삭제하고 새로운 라이러리로 마레이션 진행였습니다. 이 에서는 Google Identity Services 활용 Google 로그인 구현 방법을 설명합니다.

 

1. 사 준비

GCP에서 Client ID 

Google Cloud Platform에서 Client ID를 발급받아 합니다. 이 과정 생하였으며, 관련 자료 구 통해 쉽게 찾 수 있습니다.
 
2. Google Login 구현

2.1. Typescript 설정 (google.d.ts)

Google Identity Services는 타입 제공하지 므로, 필요한 타입 직접 선언해야 합니다. .d.ts 파일을 생성하여 window.google 타입을 정의합니다.

구글에서 공식적으로 타입을 제공하진 않지만 인터넷 상에서 공유된 것이 있었습니다. reference를 참고하여 필요한 것을 추가하였습니다.

interface IdConfiguration {
  client_id: string;
  auto_select?: boolean;
  callback: (handleCredentialResponse: CredentialResponse) => void;
  login_uri?: string;
  native_callback?: (...args: any[]) => void;
  cancel_on_tap_outside?: boolean;
  prompt_parent_id?: string;
  nonce?: string;
  context?: string;
  state_cookie_domain?: string;
  ux_mode?: 'popup' | 'redirect';
  allowed_parent_origin?: string | string[];
  intermediate_iframe_close_callback?: (...args: any[]) => void;
}

interface ICredential {
  iss: string; // The JWT's issuer
  nbf: number;
  aud: string; // Your server's client ID
  sub: string; // The unique ID of the user's Google Account
  hd: string; // If present, the host domain of the user's GSuite email address
  email: string; // The user's email address
  email_verified: boolean; // true, if Google has verified the email address
  azp: string;
  name: string; // If present, a URL to user's profile picture
  picture: string;
  given_name: string;
  family_name: string;
  iat: number; // Unix timestamp of the assertion's creation time
  exp: number; // Unix timestamp of the assertion's expiration time
  jti: string;
}

interface CredentialResponse {
  credential?: string;
  select_by?:
    | 'auto'
    | 'user'
    | 'user_1tap'
    | 'user_2tap'
    | 'btn'
    | 'btn_confirm'
    | 'brn_add_session'
    | 'btn_confirm_add_session';
  clientId?: string;
}

interface GsiButtonConfiguration {
  type: 'standard' | 'icon';
  theme?: 'outline' | 'filled_blue' | 'filled_black';
  size?: 'large' | 'medium' | 'small';
  text?: 'signin_with' | 'signup_with' | 'continue_with' | 'signup_with';
  shape?: 'rectangular' | 'pill' | 'circle' | 'square';
  logo_alignment?: 'left' | 'center';
  width?: string;
  local?: string;
}

interface PromptMomentNotification {
  isDisplayMoment: () => boolean;
  isDisplayed: () => boolean;
  isNotDisplayed: () => boolean;
  getNotDisplayedReason: () =>
    | 'browser_not_supported'
    | 'invalid_client'
    | 'missing_client_id'
    | 'opt_out_or_no_session'
    | 'secure_http_required'
    | 'suppressed_by_user'
    | 'unregistered_origin'
    | 'unknown_reason';
  isSkippedMoment: () => boolean;
  getSkippedReason: () =>
    | 'auto_cancel'
    | 'user_cancel'
    | 'tap_outside'
    | 'issuing_failed';
  isDismissedMoment: () => boolean;
  getDismissedReason: () =>
    | 'credential_returned'
    | 'cancel_called'
    | 'flow_restarted';
  getMomentType: () => 'display' | 'skipped' | 'dismissed';
}

interface RevocationResponse {
  successful: boolean;
  error: string;
}

interface Credential {
  id: string;
  password: string;
}

interface Google {
  accounts: {
    id: {
      initialize: (input: IdConfiguration) => void;
      prompt: (
        momentListener?: (res: PromptMomentNotification) => void,
      ) => void;
      renderButton: (
        parent: HTMLElement,
        options: GsiButtonConfiguration,
      ) => void;
      disableAutoSelect: () => void;
      storeCredential: (credentials: Credential, callback: () => void) => void;
      cancel: () => void;
      onGoogleLibraryLoad: () => void;
      revoke: (
        hint: string,
        callback: (done: RevocationResponse) => void,
      ) => void;
    };
  };
}

interface Window {
  google?: Google;
}
2.2. index.html 설정

Google Identity Services를 사용하기 위해 index.html 파일 크립트를 추가합니다.

2.3. GoogleLogin  구현

React 넌트에서 Google 로그인 버튼을 렌하고, 로그인 성공 시 콜 처리합니다.

유저 데이터가 JWT 형태로 리턴되도록 변경되었기 때문에 decode가 필요합니다.

3. 참고 자료

 

 

 

 

 

 

린 부분 있다면 알려시면 감사하겠습니다!