電話認證

電話身份驗證允許用戶使用他們的電話作為身份驗證器登錄 Firebase。包含唯一代碼的 SMS 消息(使用提供的電話號碼)發送給用戶。一旦代碼獲得授權,用戶就可以登錄 Firebase。

最終用戶提供的用於身份驗證的電話號碼將由 Google 發送和存儲,以改進整個 Google 服務(包括但不限於 Firebase)的垃圾郵件和濫用防護。開發人員應確保在使用 Firebase 身份驗證電話號碼登錄服務之前獲得適當的最終用戶同意。

並非所有國家/地區都支持 Firebase 電話身份驗證。請參閱他們的常見問題解答以獲取更多信息。

設置

在開始電話身份驗證之前,請確保您已按照以下步驟操作:

  1. Firebase 控制台中啟用電話作為登錄方法。
  2. Android :如果您尚未在Firebase 控制台中設置應用的 SHA-1 哈希,請執行此操作。有關查找應用程序的 SHA-1 哈希的信息,請參閱驗證您的客戶端
  3. iOS :在 Xcode 中,為您的項目啟用推送通知並確保您的 APNs 身份驗證密鑰已配置為 Firebase Cloud Messaging (FCM) 。要查看此步驟的深入說明,請查看Firebase iOS 電話身份驗證文檔。
  4. Web :確保您已在Firebase 控制台OAuth 重定向域下添加了您的應用程序域

注意;電話號碼登錄僅適用於真實設備和網絡。要在設備模擬器上測試您的身份驗證流程,請參閱測試

用法

適用於 Flutter 的 Firebase 身份驗證 SDK 提供了兩種使用電話號碼登錄用戶的單獨方法。本機(例如 Android 和 iOS)平台提供的驗證電話號碼的功能與 Web 不同,因此每個平台都存在兩種專門的方法:

  • 原生平台verifyPhoneNumber
  • 網絡平台signInWithPhoneNumber

原生: verifyPhoneNumber

在本機平台上,必須先驗證用戶的電話號碼,然後用戶才能登錄或將其帳戶與PhoneAuthCredential

首先,您必須提示用戶輸入他們的電話號碼。提供後,調用verifyPhoneNumber()方法:

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

您必須處理 4 個單獨的回調,每個回調都將決定您如何更新應用程序 UI:

  1. verifyCompleted :自動處理 Android 設備上的 SMS 代碼。
  2. verifyFailed :處理電話號碼無效或是否超出短信配額等失敗事件。
  3. codeSent :當 Firebase 向設備發送代碼時處理,用於提示用戶輸入代碼。
  4. codeAutoRetrievalTimeout :處理自動 SMS 代碼處理失敗時的超時。

驗證完成

此處理程序只會在支持自動 SMS 代碼解析的 Android 設備上調用。

短信驗證碼發送到設備後,Android 會自動驗證短信驗證碼,無需用戶手動輸入驗證碼。如果發生此事件,將自動提供一個PhoneAuthCredential ,可用於登錄或鏈接用戶的電話號碼。

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

驗證失敗

如果 Firebase 返回錯誤,例如電話號碼不正確或項目的 SMS 配額已超出,則會向此處理程序發送FirebaseAuthException 。在這種情況下,您會根據錯誤代碼提示您的用戶出了點問題。

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

代碼發送

當 Firebase 向設備發送 SMS 代碼時,會使用verificationIdresendToken觸發此處理程序( resendToken僅在 Android 設備上支持,iOS 設備將始終返回null值)。

一旦觸發,現在是更新應用程序 UI 以提示用戶輸入他們期望的 SMS 代碼的好時機。輸入 SMS 代碼後,您可以將驗證 ID 與 SMS 代碼組合以創建新的PhoneAuthCredential

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

默認情況下,如果最近發送過新的 SMS 消息,Firebase 不會重新發送。但是,您可以通過將帶有重新發送令牌的verifyPhoneNumber方法重新調用到forceResendingToken參數來覆蓋此行為。如果成功,將重新發送 SMS 消息。

代碼自動檢索超時

在支持自動 SMS 代碼解析的 Android 設備上,如果設備在特定時間範圍內沒有自動解析 SMS 消息,則會調用此處理程序。時間範圍過後,設備將不再嘗試解析任何傳入消息。

默認情況下,設備等待 30 秒,但可以使用timeout參數自定義:

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

網站: signInWithPhoneNumber

在 Web 平台上,用戶可以通過輸入發送到提供的電話號碼的 SMS 代碼來確認他們可以使用電話來登錄。為了增加安全性和防止垃圾郵件,用戶需要通過完成Google reCAPTCHA小部件來證明他們是人類。確認後,將發送短信代碼。

默認情況下,Flutter 的 Firebase 身份驗證 SDK 將開箱即用地管理 reCAPTCHA 小部件,但如果需要,可以控制它的顯示和配置方式。要開始使用,請使用電話號碼調用signInWithPhoneNumber方法。

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

調用該方法將首先觸發 reCAPTCHA 小部件顯示。用戶必須在發送 SMS 代碼之前完成測試。完成後,您可以通過向已解析的ConfirmationResult響應中的confirm方法提供 SMS 代碼來登錄用戶:

UserCredential userCredential = await confirmationResult.confirm('123456');

與其他登錄流程一樣,成功登錄將觸發您在整個應用程序中訂閱的任何身份驗證狀態偵聽器。

reCAPTCHA 配置

reCAPTCHA 小部件是一個完全託管的流程,可為您的 Web 應用程序提供安全性。

signInWithPhoneNumber的第二個參數接受一個可選的RecaptchaVerifier實例,該實例可用於管理小部件。默認情況下,當觸發登錄流程時,小部件將呈現為不可見的小部件。一個“不可見”的小部件將在您的應用程序頂部顯示為整頁模式。

然而,可以顯示一個內聯小部件,用戶必須明確按下該小部件來驗證自己。

要添加內聯小部件,請為RecaptchaVerifier實例的container參數指定一個 DOM 元素 ID。該元素必須存在並且為空,否則將引發錯誤。如果未提供container參數,則小部件將呈現為“不可見”。

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

您可以選擇通過自定義sizetheme參數來更改大小和主題,如上所示。

也可以監聽事件,比如reCAPTCHA是否已經被用戶完成,reCAPTCHA是否過期或者是否拋出錯誤:

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

測試

Firebase 支持本地測試電話號碼:

  1. 在 Firebase 控制台上,選擇“電話”身份驗證提供程序,然後單擊“用於測試的電話號碼”下拉菜單。
  2. 輸入一個新的電話號碼(例如+44 7444 555666 )和一個測試代碼(例如123456 )。

如果向verifyPhoneNumbersignInWithPhoneNumber方法提供測試電話號碼,則實際上不會發送 SMS。您可以改為直接將測試代碼提供​​給PhoneAuthProvider或使用signInWithPhoneNumber的確認結果處理程序。