透過 OIDC 登入使用者

本文說明如何使用 Identity Platform,透過 OpenID Connect (OIDC) 提供者登入使用者帳戶。

事前準備

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. 啟用 Identity Platform,並將用戶端 SDK 新增至應用程式。如要瞭解做法,請參閱快速入門
  7. 設定提供者

    1. 前往 Google Cloud 控制台的「Identity Providers」(識別資訊提供者) 頁面。
      前往「Identity Providers」(識別資訊提供者) 頁面

    2. 按一下「新增供應商」,然後從清單中選取「OpenID Connect」

    授權碼流程

    1. 輸入下列詳細資料,啟用授權碼流程:

      1. 在「選擇授權類型」部分下方,選取「程式碼流程」

      2. 供應商名稱。這可以與供應商 ID 相同,也可以是自訂名稱。如果輸入自訂名稱,請按一下「供應商 ID」旁的「編輯」,指定 ID (必須以 oidc. 開頭)。

      3. 供應商的用戶端 ID

      4. 供應商的「核發單位」。這應該會類似 https://example.com。Identity Platform 會使用這個網址尋找 OIDC 探索文件 (通常位於 /.well-known/openid-configuration),該文件會指定供應商的 OAuth 端點和公開金鑰。

      5. 供應商的用戶端密鑰

    2. 將應用程式新增至「已授權網域」清單。舉例來說,如果應用程式的登入網址為 https://example.com/login,請新增 example.com

    3. 向 OIDC 供應商設定 Identity Platform 回呼網址做為重新導向網址。網址應類似於 https://[PROJECT-ID].firebaseapp.com/__/auth/handler

    4. 按一下 [儲存]

    隱含流程

    1. 輸入下列詳細資料,啟用隱含流程:

      1. 在「Choose grant type」(選擇授權類型) 部分下方,選取「Implicit Flow」(隱含流程)

      2. 供應商名稱。這可以與供應商 ID 相同,也可以是自訂名稱。如果輸入自訂名稱,請按一下「供應商 ID」旁的「編輯」,指定 ID (必須以 oidc. 開頭)。

      3. 供應商的用戶端 ID

      4. 供應商的「核發單位」。這看起來應該會像這樣: https://example.com. Identity Platform 會使用這個網址尋找 OIDC 探索文件 (通常位於 /.well-known/openid-configuration),該文件會指定供應商的 OAuth 端點和公開金鑰。

    2. 將應用程式新增至「已授權網域」清單。舉例來說,如果應用程式的登入網址為 https://example.com/login,請新增 example.com

    3. 向 OIDC 供應商設定 Identity Platform 回呼網址做為重新導向網址。網址應類似於 https://[PROJECT-ID].firebaseapp.com/__/auth/handler

    4. 按一下 [儲存]

    登入的使用者

    透過 OIDC 登入使用者的方式有兩種:

    • 使用 OAuth 流程。這樣一來,系統就會為您完成 OAuth 握手程序。根據設定供應商步驟中選取的授權碼流程/隱含流程,GCIP 伺服器會選擇與身分識別供應商通訊的所需流程。

    • 使用 OIDC 供應商的 ID 權杖。這個方法假設您已取得 OIDC 權杖。

    透過 OAuth 登入使用者

    如要使用 OAuth 登入,請按照下列步驟操作:

    1. 使用您在前一節中設定的供應商 ID,建立 OAuthProvider 執行個體。提供者 ID 的開頭必須是 oidc.

      網頁版 9

      import { OAuthProvider } from "firebase/auth";
      
      const provider = new OAuthProvider("oidc.myProvider");

      網頁版 8

      const provider = new firebase.auth.OAuthProvider('oidc.myProvider');
    2. 啟動登入流程。你可以選擇使用彈出式視窗或重新導向。

      網頁版 9

      import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      signInWithPopup(auth, provider)
        .then((result) => {
          // User is signed in.
          const credential = OAuthProvider.credentialFromResult(result);
          // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider
        }).catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The AuthCredential type that was used.
          const credential = OAuthProvider.credentialFromError(error);
          // Handle / display error.
          // ...
        });

      網頁版 8

      firebase.auth().signInWithPopup(provider)
        .then((result) => {
          // User is signed in.
          // result.credential is a firebase.auth().OAuthCredential object.
          // result.credential.providerId is equal to 'oidc.myProvider'.
          // result.credential.idToken is the OIDC provider's ID token.
        })
        .catch((error) => {
          // Handle error.
        });

      重新導向

      如要重新導向至登入頁面,請呼叫 signInWithRedirect()

      網頁版 9

      import { getAuth, signInWithRedirect } from "firebase/auth";
      
      const auth = getAuth();
      signInWithRedirect(auth, provider);

      網頁版 8

      firebase.auth().signInWithRedirect(provider).catch((error) => {
        // Handle error.
      });

      接著,在使用者返回應用程式時呼叫 getRedirectResult() 取得結果:

      網頁版 9

      import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
      
      const auth = getAuth();
      getRedirectResult(auth)
        .then((result) => {
          // User is signed in.
          const credential = OAuthProvider.credentialFromResult(result);
          // This gives you an access token for the OIDC provider. You can use it to directly interact with that provider
        })
        .catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The AuthCredential type that was used.
          const credential = OAuthProvider.credentialFromError(error);
          // Handle / display error.
          // ...
        });

      網頁版 8

      // On return.
      firebase.auth().getRedirectResult()
        .then((result) => {
          // User is signed in.
          // result.credential is a firebase.auth().OAuthCredential object.
          // result.credential.providerId is equal to 'oidc.myProvider'.
          // result.credential.idToken is the OIDC provider's ID token.
        })
        .catch((error) => {
          // Handle / display error.
          // ...
        });

    任一流程結束後,您可以使用 result.credential.idToken 欄位取得 OIDC ID 權杖。

    直接登入使用者

    如要直接使用 OIDC ID 權杖登入使用者,請按照下列步驟操作:

    1. 使用您在前一節中設定的提供者 ID,初始化 OAuthProvider 執行個體。提供者 ID 的開頭必須是 oidc.。接著建立 OAuthCredential,並呼叫 signInWithCredential() 讓使用者登入。

      網頁版 9

      import { getAuth, OAuthProvider, signInWithCredential } from "firebase/auth";
      
      const auth = getAuth();
      const credential = provider.credential({
        idToken: oidcIdToken,
      });
      signInWithCredential(auth, credential)
        .then((result) => {
          // User is signed in.
          const newCredential = OAuthProvider.credentialFromResult(result);
          // This gives you a new access token for the OIDC provider. You can use it to directly interact with that provider.
        })
        .catch((error) => {
          // Handle Errors here.
          const errorCode = error.code;
          const errorMessage = error.message;
          // The email of the user's account used.
          const email = error.customData.email;
          // The AuthCredential type that was used.
          const credential = OAuthProvider.credentialFromError(error);
          // Handle / display error.
          // ...
        });

      網頁版 8

      const credential = provider.credential(oidcIdToken, null);
      
      firebase.auth().signInWithCredential(credential)
        .then((result) => {
          // User is signed in.
          // User now has a odic.myProvider UserInfo in providerData.
        })
        .catch((error) => {
          // Handle / display error.
          // ...
        });

    連結使用者帳戶

    如果使用者已透過其他方法 (例如電子郵件/密碼) 登入應用程式,您可以使用 linkWithPopup()linkWithRedirect(),將現有帳戶連結至 OIDC 供應商: 舉例來說,我們可以連結至 Google 帳戶:

    網頁版 9

    import { getAuth, linkWithPopup, GoogleAuthProvider } from "firebase/auth";
    const provider = new GoogleAuthProvider();
    
    const auth = getAuth();
    linkWithPopup(auth.currentUser, provider).then((result) => {
      // Accounts successfully linked.
      const credential = GoogleAuthProvider.credentialFromResult(result);
      const user = result.user;
      // ...
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

    網頁版 8

    auth.currentUser.linkWithPopup(provider).then((result) => {
      // Accounts successfully linked.
      var credential = result.credential;
      var user = result.user;
      // ...
    }).catch((error) => {
      // Handle Errors here.
      // ...
    });

    後續步驟