進階驗證功能

1. 設定

取得原始碼

在本程式碼研究室中,您會從近乎完成的 Friendly Chat 範例應用程式版本開始操作,因此首先需要複製原始碼:

$ git clone https://github.com/firebase/codelab-friendlychat-web --branch security

接著,請移至 security-start 目錄,您將在本程式碼研究室的其餘部分使用這個目錄:

$ cd codelab-friendlychat-web/security-start

現在請安裝依附元件,以便執行程式碼。如果網際網路連線速度較慢,可能需要一到兩分鐘:

$ npm install && (cd functions && npm install)

認識這個存放區

security-solution/ 目錄包含範例應用程式的完整程式碼。您將在 security-start 目錄中完成程式碼研究室,但驗證實作部分缺少幾個重要部分。security-start/security-solution/ 中的主要檔案和功能包括:

  • functions/index.js 包含 Cloud Functions 程式碼,您將在其中編寫驗證封鎖函式。
  • public/ - 包含即時通訊應用程式的靜態檔案
  • public/scripts/main.js - 聊天機器人應用程式的 JS 程式碼 (src/index.js) 會編譯至此
  • src/firebase-config.js - 包含用於初始化即時通訊應用程式的 Firebase 設定物件
  • src/index.js - Chat 擴充應用程式的 JS 程式碼

取得 Firebase CLI

模擬器套件是 Firebase CLI (指令列介面) 的一部分,您可以使用下列指令在電腦上安裝:

$ npm install -g firebase-tools@latest

使用 webpack 建構 JavaScript,這會在 public/scripts/ 目錄中建立 main.js。

webpack build

接著,請確認您使用的是最新版 CLI。本程式碼實驗室適用於 11.14 以上版本。

$ firebase --version
11.14.2

連結至 Firebase 專案

建立新的 Firebase 專案

  1. 使用 Google 帳戶登入 Firebase 控制台
  2. 按一下按鈕建立新專案,然後輸入專案名稱 (例如 Authentication MFA Codelab)。
  3. 按一下「繼續」
  4. 如果系統提示,請詳閱並接受 Firebase 條款,然後按一下「繼續」
  5. (選用) 在 Firebase 控制台中啟用 AI 輔助功能 (稱為「Gemini in Firebase」)。
  6. 本程式碼研究室不需要 Google Analytics,因此請關閉 Google Analytics 選項。
  7. 按一下「建立專案」,等待專案佈建完成,然後按一下「繼續」

將程式碼連結至 Firebase 專案

現在請將這組代碼連結至 Firebase 專案。首先,請執行下列指令登入 Firebase CLI:

$ firebase login

接著執行下列指令,建立專案別名。將 $YOUR_PROJECT_ID 替換為 Firebase 專案的 ID。

$ firebase use $YOUR_PROJECT_ID

現在可以執行應用程式了!

2. 執行模擬器

在本節中,您將在本機執行應用程式。這表示該啟動 Emulator Suite 了。

啟動模擬器

在程式碼研究室來源目錄中,執行下列指令來啟動模擬器:

$ firebase emulators:start

這會在 http://127.0.0.1:5170 提供應用程式,並在您進行變更時持續重建原始碼。您只需要在瀏覽器中強制重新整理 (Ctrl + Shift + R),即可查看變更。

輸出內容會類似這樣:

i  emulators: Starting emulators: auth, functions, firestore, hosting, storage
✔  functions: Using node@16 from host.
i  firestore: Firestore Emulator logging to firestore-debug.log
✔  firestore: Firestore Emulator UI websocket is running on 9150.
i  hosting[demo-example]: Serving hosting files from: ./public
✔  hosting[demo-example]: Local server: http://127.0.0.1:5170
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "[...]" for Cloud Functions...
✔  functions: Loaded functions definitions from source: beforecreated.
✔  functions[us-central1-beforecreated]: providers/cloud.auth/eventTypes/user.beforeCreate function initialized (http://127.0.0.1:5011/[...]/us-central1/beforecreated).
i  Running script: npm start
 
> security@1.0.0 start
> webpack --watch --progress
[...]
webpack 5.50.0 compiled with 1 warning in 990 ms

看到「All emulators ready」(所有模擬器都已準備就緒) 訊息後,即可使用應用程式。

3. 實作 MFA

這個存放區已部分實作 MFA。您將新增程式碼,先為使用者啟用多重驗證,然後提示已啟用多重驗證的使用者提供第二個驗證因素。

在編輯器中開啟 src/index.js 檔案,然後找出 startEnrollMultiFactor() 方法。新增下列程式碼,設定 reCAPTCHA 驗證器來防範手機濫用行為 (reCAPTCHA 驗證器會設為隱形,使用者不會看到):

async function startEnrollMultiFactor(phoneNumber) {
  const recaptchaVerifier = new RecaptchaVerifier(
    "recaptcha",
    { size: "invisible" },
    getAuth()
  );

接著,找出 finishEnrollMultiFactor() 方法,並新增下列內容來註冊第二個驗證因素:

// Completes MFA enrollment once a verification code is obtained.
async function finishEnrollMultiFactor(verificationCode) {
  // Ask user for the verification code. Then:
  const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
  const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
 
  // Complete enrollment.
  await multiFactor(getAuth().currentUser)
    .enroll(multiFactorAssertion)
    .catch(function (error) {
      alert(`Error finishing second factor enrollment. ${error}`);
      throw error;
    });
  verificationId = null;
}

接著,找出 signIn 函式,並加入下列控制流程,提示已啟用多重驗證的使用者輸入第二個驗證要素:

async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider)
    .then(function (userCredential) {
      // User successfully signed in and is not enrolled with a second factor.
    })
    .catch(function (error) {
      if (error.code == "auth/multi-factor-auth-required") {
        multiFactorResolver = getMultiFactorResolver(getAuth(), error);
        displaySecondFactor(multiFactorResolver.hints);
      } else {
        alert(`Error signing in user. ${error}`);
      }
    });
}

包括在此處叫用的函式在內,其餘實作程序都已完成。如要瞭解這些函式的運作方式,請瀏覽檔案的其餘部分。

4. 在模擬器中嘗試使用多重驗證登入

現在試試看 MFA 實作成果!確認模擬器仍在執行中,並前往 localhost:5170 存取本機代管的應用程式。嘗試登入,系統提示您提供多重驗證碼時,終端視窗中就會顯示多重驗證碼。

由於模擬器完全支援多重驗證,因此開發環境可以完全獨立運作。

如要進一步瞭解如何實作多重驗證,請參閱參考文件

5. 建立封鎖函式

部分應用程式僅供特定使用者群組使用。在這種情況下,您會希望能夠為使用者註冊或登入應用程式建立自訂規定。

封鎖函式可提供自訂驗證需求的方法。這些函式是 Cloud Functions,但與大多數函式不同,使用者嘗試註冊或登入時,這些函式會同步執行。

如要建立封鎖函式,請在編輯器中開啟 functions/index.js,並找出已註解的 beforecreated 函式。

將其替換為以下程式碼,只允許網域為 example.com 的使用者建立帳戶:

exports.beforecreated = beforeUserCreated((event) => {
  const user = event.data;
  // Only users of a specific domain can sign up.
  if (!user.email || !user.email.endsWith("@example.com")) {
    throw new HttpsError("invalid-argument", "Unauthorized email");
  }
});

6. 在模擬器中試用封鎖函式

如要試用封鎖功能,請確認模擬器正在執行,並在 localhost:5170 的網路應用程式中登出。

然後嘗試使用結尾不是 example.com 的電子郵件地址建立帳戶。封鎖函式會導致作業失敗。

現在請使用結尾為 example.com 的電子郵件地址再試一次。帳戶就會建立成功。

您可以使用封鎖函式,建立驗證相關的任何限制。詳情請參閱參考說明文件

重點回顧

做得好!您在網頁應用程式中新增了多重驗證,協助使用者保護帳戶安全,然後使用封鎖函式為使用者建立自訂註冊規定。你絕對值得獲得 GIF!

辦公室同事跳「舉高雙手」舞的 GIF