進階身份驗證功能

1. 設定

取得原始碼

在此 Codelab 中,您將從接近完成的 Friendship 範例應用程式版本開始,因此您需要做的第一件事是克隆原始程式碼:

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

然後,進入security-start目錄,您將在其中完成本 Codelab 的剩餘部分:

$ cd codelab-friendlychat-web/security-start

現在,安裝依賴項以便您可以運行程式碼。如果您的網路連線速度較慢,這可能需要一兩分鐘:

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

了解這個倉庫

security-solution/目錄包含範例應用程式的完整程式碼。 security-start目錄是您完成 Codelab 的位置,並且缺少身份驗證實作的一些重要部分。 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 - 您的聊天應用程式 JS 程式碼

取得 Firebase CLI

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

$ npm install -g firebase-tools@latest

使用 webpack 建立 javascript,這將在 public/scripts/ 目錄中建立 main.js。

webpack build

接下來,確認您擁有最新版本的 CLI。此 Codelab 適用於 11.14 或更高版本。

$ firebase --version
11.14.2

連接到您的 Firebase 項目

如果您沒有 Firebase 項目,請在Firebase 控制台中建立一個新的 Firebase 項目。記下您選擇的項目 ID,稍後您將需要它。

現在您需要將此程式碼連接到您的 Firebase 專案。首先執行以下命令登入Firebase CLI:

$ firebase login

接下來執行以下命令來建立專案別名。將$YOUR_PROJECT_ID替換為您的 Firebase 專案的 ID。

$ firebase use $YOUR_PROJECT_ID

現在您已準備好運行該應用程式了!

2.運行模擬器

在本部分中,您將在本地運行該應用程式。這意味著是時候啟動模擬器套件了。

啟動模擬器

在 Codelab 來源目錄中,執行以下命令來啟動模擬器:

$ 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

當您看到“所有模擬器均已就緒”訊息後,該應用程式就可以使用了。

3. 實施MFA

MFA 已在此儲存庫中部分實作。您將新增程式碼以先在 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函數並新增以下控制流,提示註冊 MFA 的使用者輸入第二個因素:

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 登入

現在試試 MFA 實施!確保您的模擬器仍在運行並存取本地託管的應用程式localhost:5170 。嘗試登錄,當系統提示您提供 MFA 代碼時,您將在終端視窗中看到 MFA 代碼。

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

要了解有關實施 MFA 的更多信息,請參閱我們的參考文件

5. 建立阻塞函數

某些應用程式僅供特定使用者群組使用。對於這些情況,您希望能夠為使用者註冊或登入您的應用程式建立自訂要求。

這就是阻止函數所提供的:一種建立自訂身份驗證要求的方法。它們是雲端函數,但與大多數函數不同,它們在使用者嘗試註冊或登入時同步運行。

若要建立阻塞函數,請在編輯器中開啟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的 Web 應用程式中登出。

然後,嘗試使用不以example.com結尾的電子郵件地址建立帳戶。阻塞功能將阻止操作成功。

現在,使用以example.com結尾的電子郵件地址重試。帳戶將創建成功。

透過封鎖功能,您可以建立有關身份驗證所需的任何限制。要了解更多信息,請參閱參考文件

回顧

做得好!您為 Web 應用程式新增了多重驗證,以協助使用者確保其帳戶安全,然後為使用者使用封鎖功能進行註冊建立了自訂要求。您絕對贏得了 gif 動圖!

辦公室人員跳屋頂舞的 gif