使用 FirebaseUI 建立登入頁面

如要搭配 Identity-Aware Proxy (IAP) 使用外部身分,應用程式必須有登入頁面。IAP 會將使用者重新導向至這個頁面,以便使用者通過驗證,存取安全資源。

本文說明如何使用開放原始碼的 JavaScript 程式庫 FirebaseUI 建立驗證頁面。FirebaseUI 提供可自訂的元素,有助於減少樣板程式碼,並處理使用者透過各種識別資訊提供者登入的流程。

如要加快上手速度,請讓 IAP 為您代管 UI。您不必編寫任何額外程式碼,即可試用外部身分。如要處理更進階的案例,您也可以從頭開始建構自己的登入頁面。這個選項較為複雜,但可讓你全面掌控驗證流程和使用者體驗。

事前準備

啟用外部身分,並在設定期間選取「I'll provide my own UI」選項。

安裝程式庫

請安裝 gcip-iapfirebasefirebaseui 程式庫。gcip-iap 模組會抽象化應用程式、IAP 和 Identity Platform 之間的通訊。firebasefirebaseui 程式庫提供驗證 UI 的建構區塊。

npm install firebase --save
npm install firebaseui --save
npm install gcip-iap --save

請注意,使用 CDN 時無法使用 gcip-iap 模組。

接著,您可以在來源檔案中 import 模組。請使用適用於您 SDK 版本的正確匯入項目:

gcip-iap v0.1.4 或更早版本

// Import firebase modules.
import * as firebase from "firebase/app";
import "firebase/auth";
// Import firebaseui module.
import * as firebaseui from 'firebaseui'
// Import gcip-iap module.
import * as ciap from 'gcip-iap';

gcip-iap v1.0.0 以上版本

自 v1.0.0 版起,gcip-iap 需要 firebase v9 以上的對等依附元件。如要遷移至 gcip-iap v1.0.0 以上版本,請完成下列動作:

  • package.json 檔案中的 firebasefirebaseui 版本分別更新為 v9.6.0 以上和 v6.0.0 以上。
  • firebase 匯入陳述式更新如下:
// Import firebase modules.
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
// Import firebaseui module.
import * as firebaseui from 'firebaseui'
// Import gcip-iap module.

不需要變更其他程式碼。

如需其他安裝選項,包括使用程式庫的本地化版本,請參閱 GitHub 上的操作說明

設定應用程式

FirebaseUI 會使用設定物件,指定用於驗證的房客和供應商。完整設定可能很長,看起來會像這樣:

// The project configuration.
const configs = {
  // Configuration for project identified by API key API_KEY1.
  API_KEY1: {
    authDomain: 'project-id1.firebaseapp.com',
    // Decide whether to ask user for identifier to figure out
    // what tenant to select or whether to present all the tenants to select from.
    displayMode: 'optionFirst', // Or identifierFirst
    // The terms of service URL and privacy policy URL for the page
    // where the user select tenant or enter email for tenant/provider
    // matching.
    tosUrl: 'http://localhost/tos',
    privacyPolicyUrl: 'http://localhost/privacypolicy',
    callbacks: {
      // The callback to trigger when the selection tenant page
      // or enter email for tenant matching page is shown.
      selectTenantUiShown: () => {
        // Show title and additional display info.
      },
      // The callback to trigger when the sign-in page
      // is shown.
      signInUiShown: (tenantId) => {
        // Show tenant title and additional display info.
      },
      beforeSignInSuccess: (user) => {
        // Do additional processing on user before sign-in is
        // complete.
        return Promise.resolve(user);
      }
    },
    tenants: {
      // Tenant configuration for tenant ID tenantId1.
      tenantId1: {
        // Full label, display name, button color and icon URL of the
        // tenant selection button. Only needed if you are
        // using the option first option.
        fullLabel: 'ACME Portal',
        displayName: 'ACME',
        buttonColor: '#2F2F2F',
        iconUrl: '<icon-url-of-sign-in-button>',
         // Sign-in providers enabled for tenantId1.
        signInOptions: [
          // Microsoft sign-in.
          {
            provider: 'microsoft.com',
            providerName: 'Microsoft',
            buttonColor: '#2F2F2F',
            iconUrl: '<icon-url-of-sign-in-button>',
            loginHintKey: 'login_hint'
          },
          // Email/password sign-in.
          {
            provider: 'password',
            // Do not require display name on sign up.
            requireDisplayName: false,
            disableSignUp: {
              // Disable user from signing up with email providers.
              status: true,
              adminEmail: 'admin@example.com',
              helpLink: 'https://www.example.com/trouble_signing_in'
            }
          },
          // SAML provider. (multiple SAML providers can be passed)
          {
            provider: 'saml.my-provider1',
            providerName: 'SAML provider',
            fullLabel: 'Employee Login',
            buttonColor: '#4666FF',