透過 JavaScript 使用電話號碼向 Firebase 驗證

您可以使用 Firebase Authentication 傳送簡訊來登入使用者 傳送到使用者的手機上使用者透過 簡訊。

如要在應用程式中新增電話號碼登入程序,最簡單的方法是使用 FirebaseUI, 包含用於實作手機登入流程的置入登入小工具 以及密碼和聯合登入。這份文件 說明如何使用 Firebase SDK 導入電話號碼登入流程。

事前準備

如果尚未複製,請複製 依 所述,對專案 Firebase 控制台 將 Firebase 新增至您的 JavaScript 專案。

安全疑慮

僅使用電話號碼進行驗證,安全性較低 其他可用的方法,因為擁有電話號碼 可以在使用者之間輕鬆轉移此外,當多位使用者共用裝置時 設定檔,任何可接收簡訊的使用者,皆可透過 裝置的電話號碼。

如果您在應用程式中使用電話號碼登入功能,則應提供這項功能 提供更安全的登入方式,並告知使用者這項安全措施 也不必為了使用電話號碼登入而做出取捨

為 Firebase 專案啟用電話號碼登入功能

您必須先啟用電話號碼登入功能,才能透過簡訊登入使用者 方法:

  1. Firebase 控制台中開啟「驗證」專區。
  2. 在「Sign-in Method」(登入方式) 頁面中啟用電話號碼 登入方式。
  3. 在同一個網頁上,如果代管應用程式的網域並未列在 「OAuth 重新導向網域」區段,新增您的網域。請注意,localhost 不可做為代管主機 以便進行手機驗證。

設定 reCAPTCHA 驗證器

您必須先完成設定,才能使用電話號碼登入使用者 Firebase 的 reCAPTCHA 驗證器。Firebase 使用 reCAPTCHA 來防止濫用,例如: 驗證電話號碼驗證要求 設為允許應用程式的信任網域

您不需要手動設定 reCAPTCHA 用戶端。當您使用 Firebase SDK 的 RecaptchaVerifier 物件,Firebase 會自動 建立及處理任何必要的用戶端金鑰和密鑰。

RecaptchaVerifier 物件支援 隱藏 reCAPTCHA,通常無須使用者驗證,即可驗證使用者 以及 reCAPTCHA 小工具,這類小工具一律需要使用者互動 才能順利完成

您可以更新 ,再轉譯 reCAPTCHA。上述本地化內容 郵件相關規定也適用於傳送給使用者的簡訊,其中包含驗證碼。

Web

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// auth.useDeviceLanguage();

Web

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

使用隱藏式 reCAPTCHA

如要使用隱藏式 reCAPTCHA,請建立 RecaptchaVerifier 物件 且 size 參數設為 invisible 提交登入表單的按鈕 ID。例如:

Web

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Web

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

使用 reCAPTCHA 小工具

如要使用可見的 reCAPTCHA 小工具,請在網頁中建立元素,以便: 然後建立 RecaptchaVerifier 物件 並指定容器的 ID例如:

Web

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {});

Web

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

選用:指定 reCAPTCHA 參數

您可以選擇在 使用者解開答案時,所呼叫的 RecaptchaVerifier 物件 reCAPTCHA 或 reCAPTCHA 會在使用者提交表單前過期:

Web

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Web

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

選用:預先轉譯 reCAPTCHA

如果要在提交登入要求前預先轉譯 reCAPTCHA, 呼叫 render

Web

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Web

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

render 解析後,您會收到 reCAPTCHA 小工具 ID, 可用來呼叫 reCAPTCHA API:

Web

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

將驗證碼傳送至使用者的手機

如要啟動電話號碼登入程序,請向使用者顯示提示的介面 他們提供電話號碼,然後撥打 signInWithPhoneNumber:要求 Firebase 傳送 透過簡訊將驗證碼傳送至使用者手機:

  1. 取得使用者的電話號碼。

    法律要求各有不同,但我們建議的最佳做法是 並營造使用者的期待感,您應告知他們, 手機登入時,可能會收到驗證和標準簡訊 需支付簡訊費用。

  2. 呼叫 signInWithPhoneNumber 並傳遞至使用者的手機 編號和您先前建立的 RecaptchaVerifier

    Web

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    Web

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    如果 signInWithPhoneNumber 導致錯誤,請重設 reCAPTCHA,讓使用者可以再試一次:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    敬上

signInWithPhoneNumber 方法會發出 reCAPTCHA 驗證問題 如果使用者通過驗證,系統就會要求 Firebase Authentication 會將含有驗證碼的簡訊傳送至 使用者的電話。

透過驗證碼登入使用者

呼叫 signInWithPhoneNumber 成功後,請提示 使用者輸入他們透過簡訊收到的驗證碼。然後,登入 方法是將程式碼傳遞至confirm ConfirmationResult 物件已傳遞至 signInWithPhoneNumber 的執行要求處理常式 (也就是 then 區塊)。例如:

Web

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Web

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

如果呼叫 confirm 成功,使用者已成功呼叫。 登入。

取得中繼 AuthCredential 物件

如果您需要取得使用者的 AuthCredential 物件 帳戶,請傳送確認結果中的驗證碼 將驗證碼傳送到 PhoneAuthProvider.credential 呼叫 confirm

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

接著,您即可使用憑證登入使用者:

firebase.auth().signInWithCredential(credential);

使用虛構的電話號碼進行測試

您可以透過 Firebase 控制台設定開發用的虛構電話號碼。使用虛構手機進行測試 數據具有以下優點:

  • 測試電話號碼驗證,而不耗用您的使用配額。
  • 在不傳送實際簡訊的情況下,測試電話號碼的驗證方式。
  • 以相同的電話號碼連續執行測試,而不會受到限制。這個 如果未經審查人員在應用程式商店審查流程,將審查遭拒的風險降到最低 使用相同的電話號碼進行測試
  • 在開發環境中輕鬆進行測試,不需額外的工作,例如 能夠在沒有 Google Play 服務的情況下,在 iOS 模擬器或 Android 模擬器中進行開發。
  • 編寫整合測試,但這些測試不會因一般套用的安全性檢查功能而遭到封鎖 實際電話號碼

虛構電話號碼必須符合下列規定:

  1. 請務必使用虛構的電話號碼,但實際電話號碼尚未存在。 Firebase Authentication 不允許將真人使用者目前使用的電話號碼設為測試號碼。 其中一種做法是使用 555 組前置字元為美國的測試電話號碼,例如: 0933 000 000
  2. 電話號碼的格式必須正確, 限制。不過,他們仍須完成與實際使用者電話號碼相同的驗證。
  3. 您最多可以新增 10 組開發用電話號碼。
  4. 使用不易猜到和變更的測試電話號碼/驗證碼 經常更新

建立虛構的電話號碼和驗證碼

  1. Firebase 控制台中開啟 「驗證」區段。
  2. 在「登入方式」分頁中啟用電話服務供應商 (如果您尚未啟用的話)。
  3. 開啟「測試用電話號碼」選單。
  4. 提供要測試的電話號碼,例如 +1 650-555-3434
  5. 提供該特定號碼的 6 位數驗證碼,例如「654321」
  6. 新增數字。如有需要,你可以刪除電話號碼,以及 請將滑鼠遊標懸停在對應資料列上,再按一下垃圾桶圖示。

手動測試

您可以直接開始在應用程式中使用虛構的電話號碼。您可以藉此 執行手動測試,而不會發生配額問題或節流問題。 您也可以使用沒有 Google Play 服務的 iOS 模擬器或 Android 模擬器直接進行測試 已安裝。

如果您提供虛構的電話號碼並傳送驗證碼,則簡訊不會是 已傳送。您需要提供先前設定的驗證碼,才能完成簽署。 。

登入完成後,系統會使用該電話號碼建立 Firebase 使用者。 使用者和實際電話號碼使用者俱有相同的行為和屬性, Realtime Database/Cloud Firestore 和其他服務也是如此。建立期間建立的 ID 符記 這項程序與實際電話號碼使用者擁有相同的簽章。

另一種方式是透過自訂角色設定測試角色 聲明,以便區分他們為冒用使用者,以便進一步限制 資源存取權

整合測試

除了手動測試之外,Firebase Authentication 還提供 API,可協助您編寫整合測試 用於手機驗證測試這些 API 會停用 reCAPTCHA 來停用應用程式驗證功能 以及 iOS 的靜音推播通知這樣就能在自動化環境中執行自動化測試 也能輕鬆實作也用來測試 驗證流程

使用網站時,請將「appVerificationDisabledForTesting」設為 在算繪 firebase.auth.RecaptchaVerifier 之前為 true。這可以解決問題 reCAPTCHA 會自動傳遞電話號碼,你不必手動解決。注意事項 即使停用 reCAPTCHA,使用非虛構的電話號碼 完成登入。這個 API 只能使用虛構的電話號碼。

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

顯示和隱藏的模擬 reCAPTCHA 應用程式驗證器在應用程式驗證期間運作的方式不同 已停用:

  • 顯示 reCAPTCHA:顯示透過以下方式顯示的 reCAPTCHA appVerifier.render() 會在不到一秒後自動解析 或延遲時間這相當於使用者在轉譯後立即點選 reCAPTCHA。reCAPTCHA 回應會在一段時間後失效,然後再次自動解決。
  • 隱形 reCAPTCHA: 隱形 reCAPTCHA 不會在轉譯時自動解析,而是在 appVerifier.verify() 呼叫,或 reCAPTCHA 的按鈕錨點是 但延遲時間不到一秒。同樣地,回應會在一段時間後失效 只會在 appVerifier.verify() 呼叫後或 再次點選 reCAPTCHA 的按鈕錨點。

每當模擬 reCAPTCHA 解析時,對應的回呼函式就會正常觸發 傳回內容如果一併指定到期回呼,則會在到期時觸發。

後續步驟

使用者首次登入後,系統會建立新的使用者帳戶 也就是使用者的名稱和密碼 號碼或驗證提供者資訊,也就是使用者登入時使用的網址。這項新功能 帳戶儲存為 Firebase 專案的一部分,可用來識別 即可限制使用者登入專案中的所有應用程式

  • 在應用程式中得知使用者的驗證狀態,建議做法是 在 Auth 物件上設定觀察器。接著,您就能取得使用者的 User 物件的基本個人資料資訊。詳情請見 管理使用者

  • 在你的Firebase Realtime DatabaseCloud Storage中 查看安全性規則 透過 auth 變數取得已登入使用者的不重複使用者 ID。 控管使用者可以存取的資料

您可以讓使用者透過多重驗證機制登入您的應用程式 將驗證供應商憑證連結至 現有的使用者帳戶

如要登出使用者,請呼叫 signOut

Web

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});