あなたの反応アプリに新しいGoogleのサインを追加!


TLDR:スクロールダウンし、コードをコピーします.ログインロジックを追加するだけです.
この記事は以下の通りです.
  • 新しいish Google APIの簡単な紹介
  • 反応とタイプスクリプトを使用してそれを実装する方法
  • グローバルウィンドウオブジェクトに関連する型付けを追加する
  • イントロ


    Googleは最近、彼らは彼らの新しいAuthサービス“Googleのサインイン”を支持していると発表した.
    新しいサービスは2つの部分にあります.
  • ログインボタン
  • ワンタップ
  • それらについてもっと読むことができますhere .
    私たちはこの記事の最初の1つをカバーします.どのように動作し、どのようにTypesScriptと反応してそれを実装する.
    古いサービスと比較して、これははるかに使いやすいです.それはすぐに自分のようなライブラリを必要とせずにログインボタンを自分自身を実装するのに十分ですreact-google-login それは古いAPIの解決への試みです.

    グーグルAuth導入


    私はちょうどここで基礎を越えるつもりです.
    免責事項:これを行うにははるかに良い方法があります.私はどのように知って満足しているので、コメントを残す!私はこれの例を見つけることができなかったので、私は私が私の実装をポストして、うまくいけば他の誰かを助けると考えました.
    新しいAuth APIは少しトリッキーな反応を使用するときに最初にあなたの頭を取得するには、我々はそれを動作させることができます.トリックは、スクリプトがどのようにクライアントを読み込み、どのように反応の読み込みとレンダリングに合うかを理解することです.
    GoogleドキュメントはHTMLとJavaScript APIの両方をカバーし、後者を使用します.しかし、我々は反応を構築しているので、我々はほとんどのAPI APIの動作方法を理解するステップバイステップガイドを使用します.私たちはどのように負荷を反応し、要素をレンダリングするためのアカウントをする必要があります.残念なことに、我々はちょうどガイド命令のようなヘッダーに静的にそれを貼り付けることができないことを意味します.
    アフターフォローsetup process , ドキュメントはあなたのヘッダーにスクリプトタグを追加するように指示しますpublic/index.html ), しかし、我々が反応しているので、我々はそれをしないつもりです.私たちはいつ、どこでスクリプトを実行するかを制御し、Google Authクライアントを起動します.スクリプトがクライアントを開始するので、我々はこれをしています、そして、我々は我々が反応で定義する我々自身のcallback関数を渡したいです.
    // The script that runs and load the new google auth client.
    // We're not(!) adding it to our header like the guide says.
    <script src="https://accounts.google.com/gsi/client" async defer></script>
    

    レッツゲット


    まず最初に、TypesScriptでは、window オブジェクト.適切に後で修正します.
    私たちが最初に実装するのは、Google Authクライアントをロードするスクリプトを追加することです.

    問題


    Googleクライアントにそのコールバック関数を付けるのは、新しいAuth APIを使用して少し面倒に反応することです.(でももっと古いものを使ってください!)ドキュメントのように静的HTMLにスクリプトタグを追加すると、反応で定義された関数を渡すことができません.私たちは、物事のサーバー側で機能を定義することによってものを扱うことができました、しかし、私は反応の範囲内でとどまりたいです、そして、フロントエンドでこれを扱い、ログインに私のGraphicalフックを使用してください.

    プロセス


    ログインページがレンダリングされると、GoogleクライアントスクリプトをuseEffect フック.初期化関数をonLoad -そのスクリプトタグのEventListener.OnLoadイベントは、それからGoogle Authクライアントを我々のコールバックで付けて、トリガーして、初期化します.
    Googleクライアントは、魔法のように我々はすでにレンダリングされますdiv with id=g_id_signin ログインボタンを表示します.
    素敵な探し、パーソナライズされたGoogleのボタンを今すぐユーザーに表示する必要があります.

    暗号


    import { Button } from "@material-ui/core"
    import { useEffect, useState } from "react"
    
    export default function GoogleSignin() {
      const [gsiScriptLoaded, setGsiScriptLoaded] = useState(false)
      const [user, setUser] = useState(undefined)
    
      useEffect(() => {
        if (user?._id || gsiScriptLoaded) return
    
        const initializeGsi = () => {
          // Typescript will complain about window.google
          // Add types to your `react-app-env.d.ts` or //@ts-ignore it.
          if (!window.google || gsiScriptLoaded) return
    
          setGsiScriptLoaded(true)
          window.google.accounts.id.initialize({
            client_id: GOOGLE_CLIENT_ID,
            callback: handleGoogleSignIn,
          })
        }
    
        const script = document.createElement("script")
        script.src = "https://accounts.google.com/gsi/client"
        script.onload = initializeGsi
        script.async = true
        script.id = "google-client-script"
        document.querySelector("body")?.appendChild(script)
    
        return () => {
          // Cleanup function that runs when component unmounts
          window.google?.accounts.id.cancel()
          document.getElementById("google-client-script")?.remove()
        }
      }, [handleGoogleSignIn, initializeGsi, user?._id])
    
    
    
    
    const handleGoogleSignIn = (res: CredentialResponse) => {
      if (!res.clientId || !res.credential) return
    
        // Implement your login mutations and logic here.
        // Set cookies, call your backend, etc. 
    
        setUser(val.data?.login.user)
      })
    }
    
    return <Button className={"g_id_signin"} />
    
    }
    
    いくつかのより詳細な実装の詳細をここで追加してください.しかし、これはそれの要点です!あなたは少なくとも出発点としてそれを使用することができます.それが助ける望み!

    ウィンドウタイプの修正


    あなたが使っているならばcreate-react-app , あなたは既にファイルを持っているでしょうreact-app-env.d.ts プロジェクトのルートで.そこにGoogle Auth APIの種類を追加できます.APIドキュメントをタイプスクリプトに翻訳しました.私がすべての機能を使用していなかったので、若干の誤りがあるかもしれません.しかし、それは正しいはずです.
    /// <reference types="react-scripts" />
    
    interface IdConfiguration {
      client_id: string
      auto_select?: boolean
      callback: (handleCredentialResponse: CredentialResponse) => void
      login_uri?: string
      native_callback?: Function
      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?: Function
    }
    
    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 Window {
      google?: {
        accounts: {
          id: {
            initialize: (input: IdConfiguration) => void
            prompt: (
              momentListener: (res: PromptMomentNotification) => void
            ) => void
            renderButton: (
              parent: HTMLElement,
              options: GsiButtonConfiguration,
              clickHandler: Function
            ) => void
            disableAutoSelect: Function
            storeCredential: Function<{
              credentials: { id: string; password: string }
              callback: Function
            }>
            cancel: () => void
            onGoogleLibraryLoad: Function
            revoke: Function<{
              hint: string
              callback: Function<{ successful: boolean; error: string }>
            }>
          }
        }
      }
    }
    
    

    シャムレスプラグ


    あなたがこの種のものが好きで、スウェーデンで仕事を探しているならば、Gothenburgは私を殴りました!