本頁面由 Cloud Translation API 翻譯而成。
Switch to English

使用JavaScript通過Firebase和電話號碼進行身份驗證

您可以使用Firebase身份驗證通過將SMS消息發送到用戶的電話來登錄用戶。用戶使用SMS消息中包含的一次性代碼登錄。

將電話號碼登錄添加到您的應用程序最簡單的方法是使用FirebaseUI ,它包括一個插入式登錄小部件,該小部件可實現電話號碼登錄的登錄流程以及基於密碼的聯合登錄-在。本文檔介紹瞭如何使用Firebase SDK實施電話號碼登錄流程。

在你開始之前

如果尚未將初始化片段從Firebase控制台複製到您的項目,如將Firebase添加到您的JavaScript項目中所述

安全問題

僅使用電話號碼進行身份驗證雖然很方便,但比其他可用方法安全性較低,因為擁有電話號碼的身份可以在用戶之間輕鬆轉移。此外,在具有多個用戶配置文件的設備上,任何可以接收SMS消息的用戶都可以使用設備的電話號碼登錄到帳戶。

如果您在應用中使用基於電話號碼的登錄,則應將其與更安全的登錄方法一起提供,並告知用戶使用電話號碼登錄的安全權衡。

為您的Firebase項目啟用電話號碼登錄

要通過SMS登錄用戶,必須首先為Firebase項目啟用“電話號碼”登錄方法:

  1. Firebase控制台中 ,打開“ 身份驗證”部分。
  2. 在“ 登錄方法”頁面上,啟用“ 電話號碼”登錄方法。
  3. 在同一頁面上,如果OAuth重定向域部分中未列出將託管您的應用程序的 ,請添加您的域。

Firebase的電話號碼登錄請求配額足夠高,因此大多數應用程序都不會受到影響。但是,如果您需要使用電話認證登錄大量用戶,則可能需要升級定價計劃。請參閱定價頁面。

設置reCAPTCHA驗證程序

您必須先設置Firebase的reCAPTCHA驗證程序,然後才能使用其電話號碼登錄用戶。 Firebase使用reCAPTCHA來防止濫用,例如通過確保電話號碼驗證請求來自您的應用程序允許的域之一。

您無需手動設置reCAPTCHA客戶端;當您使用Firebase SDK的RecaptchaVerifier對象時,Firebase會自動創建並處理所有必要的客戶端密鑰和機密。

RecaptchaVerifier對象支持不可見的reCAPTCHA和reCAPTCHA小部件,後者通常可以在不需要任何用戶操作的情況下驗證用戶,而reCAPTCHA小部件始終需要用戶交互才能成功完成。

通過在呈現reCAPTCHA之前更新Auth實例上的語言代碼,可以將基礎呈現的reCAPTCHA本地化為用戶的首選項。前述的本地化也將應用於包含驗證碼的發送給用戶的SMS消息。

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

使用不可見的reCAPTCHA

要使用不可見的reCAPTCHA,請創建一個size參數設置為invisibleRecaptchaVerifier對象,並指定提交登錄表單的按鈕的ID。例如:

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

使用reCAPTCHA小部件

要使用可見的reCAPTCHA小部件,請在頁面上創建一個包含小部件的元素,然後創建RecaptchaVerifier對象,並在指定時指定容器的ID。例如:

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

可選:指定reCAPTCHA參數

您可以選擇在RecaptchaVerifierRecaptchaVerifier上設置回調函數,這些回調函數在用戶解決reCAPTCHA或reCAPTCHA在用戶提交表單之前過期時調用:

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

可選:預渲染reCAPTCHA

如果要在提交登錄請求之前預渲染reCAPTCHA,請調用render

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

render解析後,您將獲得reCAPTCHA的小部件ID,可用於調用reCAPTCHA API:

var recaptchaResponse = grecaptcha.getResponse(window.recaptchaWidgetId);

將驗證碼發送到用戶的手機

要啟動電話號碼登錄,請向用戶顯示一個界​​面,提示他們提供他們的電話號碼,然後調用signInWithPhoneNumber以請求Firebase通過SMS將驗證碼發送到用戶的電話:

  1. 獲取用戶的電話號碼。

    法律要求各不相同,但是作為最佳實踐並為用戶設定期望,您應該通知他們,如果他們使用電話登錄,則他們可能會收到SMS消息以進行驗證,並採用標準費率。

  2. 調用signInWithPhoneNumber ,將用戶的電話號碼和您之前創建的RecaptchaVerifier傳遞給它。
    var phoneNumber = getPhoneNumberFromUserInput();
    var appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then(function (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(function (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向用戶的手機發送包含驗證碼的SMS消息。

使用驗證碼登錄用戶

成功調用signInWithPhoneNumber ,提示用戶鍵入他們通過SMS收到的驗證碼。然後,符號在由代碼傳遞給所述用戶confirm所述的方法ConfirmationResult傳遞給對象signInWithPhoneNumber的履行處理程序(即,其then塊)。例如:

var code = getCodeFromUserInput();
confirmationResult.confirm(code).then(function (result) {
  // User signed in successfully.
  var user = result.user;
  // ...
}).catch(function (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控制台將電話號碼列入白名單進行開發。將電話號碼列入白名單可提供以下好處:

  • 在不消耗您的使用配額的情況下測試電話號碼身份驗證。
  • 測試電話號碼身份驗證,而不發送實際的SMS消息。
  • 使用相同的電話號碼連續運行測試,而不會受到限制。如果審閱者碰巧使用相同的電話號碼進行測試,則可以最大程度地減少在App Store審閱過程中被拒絕的風險。
  • 無需任何額外努力即可在開發環境中輕鬆測試,例如能夠在iOS模擬器或沒有Google Play服務的Android模擬器中進行開發。
  • 編寫集成測試,而不會受到通常在生產環境中應用於真實電話號碼的安全檢查的阻止。

列入白名單的電話號碼必須滿足以下要求:

  1. 確保使用不存在的虛構數字。 Firebase身份驗證不允許您將真實用戶使用的現有電話號碼列入白名單。一種選擇是使用555前綴號碼作為美國測試電話號碼,例如: +1 650-555-3434
  2. 電話號碼必須正確設置格式,以保證長度和其他限制。他們仍將通過與真實用戶的電話號碼相同的驗證。
  3. 您最多可以添加10個電話號碼進行開發。
  4. 使用難以猜測的測試電話號碼/代碼,並經常進行更改。

將電話號碼和驗證碼列入白名單

  1. Firebase控制台中 ,打開“ 身份驗證”部分。
  2. 在“ 登錄方法”選項卡中,如果尚未啟用,請啟用電話提供程序。
  3. 打開電話號碼以測試手風琴菜單。
  4. 提供您要測試的電話號碼,例如: +1 650-555-3434
  5. 提供該特定號碼的6位驗證碼,例如: 654321
  6. 添加號碼。如果需要,可以將鼠標懸停在相應的行上,然後單擊垃圾桶圖標,以刪除電話號碼及其代碼。

手動測試

您可以在應用程序中直接開始使用列入白名單的電話號碼。這使您可以在開發階段執行手動測試,而不會遇到配額問題或限制。您也可以直接從iOS模擬器或Android模擬器進行測試,而無需安裝Google Play服務。

提供白名單中的電話號碼並發送驗證碼時,不會發送任何實際的SMS。相反,您需要提供先前配置的驗證碼才能完成登錄。

登錄完成後,將使用該電話號碼創建一個Firebase用戶。該用戶具有與真實電話號碼用戶相同的行為和屬性,並且可以以相同方式訪問Realtime Database / Cloud Firestore和其他服務。在此過程中鑄造的ID令牌具有與真實電話號碼用戶相同的簽名。

另一個選擇是,如果您想進一步限制訪問權限,則可以通過對這些用戶的自定義聲明設置測試角色,以將其區分為假用戶。

整合測試

除了手動測試之外,Firebase身份驗證還提供API,以幫助編寫用於電話身份驗證測試的集成測試。這些API通過禁用Web中的reCAPTCHA要求和iOS中的靜默推送通知來禁用應用程序驗證。這使得在這些流程中進行自動化測試成為可能,並且更易於實現。此外,它們還有助於提供在Android上測試即時驗證流程的功能。

在網頁上,集appVerificationDisabledForTestingtrue呈現前firebase.auth.RecaptchaVerifier 。這將自動解析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 whitelisted testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

禁用應用程序驗證時,可見和不可見的模擬reCAPTCHA應用程序驗證程序的行為不同:

  • 可見的reCAPTCHA :當通過appVerifier.render()呈現可見的reCAPTCHA時,它會在幾分之一秒的延遲後自動解決。這等效於用戶在渲染後立即單擊reCAPTCHA。 reCAPTCHA響應將在一段時間後到期,然後再次自動解析。
  • 不可見的reCAPTCHA :不可見的reCAPTCHA不會在渲染時自動解析,而是在appVerifier.verify()調用上或在經過一秒鐘的延遲後單擊reCAPTCHA的按鈕錨點時自動解析。同樣,響應將在一段時間後到期,並且只會在appVerifier.verify()調用之後或再次單擊reCAPTCHA的按鈕錨點之後自動解析。

只要解析了模擬reCAPTCHA,就會以假響應按預期觸發相應的回調函數。如果還指定了過期回調,則它將在過期時觸發。

下一步

用戶首次登錄後,將創建一個新的用戶帳戶並將其鏈接到用戶登錄的憑據(即用戶名和密碼,電話號碼或身份驗證提供者信息)。此新帳戶存儲為Firebase項目的一部分,可用於在項目中的每個應用程序中識別用戶,而無論用戶如何登錄。

  • 在您的應用中,建議的了解用戶身份驗證狀態的方法是在Auth對像上設置觀察者。然後,您可以從User對象獲取用戶的基本配置文件信息。請參閱管理用戶

  • 在Firebase實時數據庫和Cloud Storage 安全規則中 ,您可以從auth變量中獲取登錄用戶的唯一用戶ID,並使用它來控制用戶可以訪問哪些數據。

通過將身份驗證提供程序憑據鏈接到現有用戶帳戶,可以允許用戶使用多個身份驗證提供程序登錄您的應用程序

要註銷用戶,請致電signOut

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