電話身份驗證允許用戶使用手機作為身份驗證器登入 Firebase。將向用戶發送包含唯一代碼的 SMS 訊息(使用提供的電話號碼)。程式碼獲得授權後,使用者就可以登入 Firebase。
最終用戶提供的用於身份驗證的電話號碼將由 Google 發送和存儲,以改善 Google 服務中的垃圾郵件和濫用行為,包括但不限於 Firebase。開發者應確保在使用 Firebase 身份驗證電話號碼登入服務之前獲得適當的最終用戶同意。身份驗證
並非所有國家/地區都支援 Firebase 電話身份驗證。請參閱他們的常見問題以獲取更多資訊。
設定
在開始使用電話身份驗證之前,請確保您已執行以下步驟:
- 在Firebase 控制台中啟用電話作為登入方式。
- Android :如果您尚未在Firebase 控制台中設定套用的 SHA-1 雜湊,請執行此操作。有關查找應用程式的 SHA-1 雜湊值的信息,請參閱驗證您的用戶端。
- iOS :在 Xcode 中,為您的專案啟用推播通知並確保您的 APNs 驗證金鑰已使用 Firebase Cloud Messaging (FCM) 配置。此外,您必須啟用遠端通知的後台模式。若要查看此步驟的深入說明,請查看Firebase iOS 手機驗證文件。
- 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 的方式:
- verifyCompleted :在 Android 裝置上自動處理 SMS 程式碼。
- verifyFailed :處理失敗事件,例如無效的電話號碼或是否超出簡訊配額。
- codeSent :當程式碼從 Firebase 傳送到裝置時進行處理,用於提示使用者輸入代碼。
- 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 程式碼時,會使用verificationId
和resendToken
觸發此處理程序( resendToken
僅在 Android 裝置上受支持,iOS 裝置將始終傳回null
值)。
一旦觸發,就應該更新應用程式 UI 以提示使用者輸入他們期望的 SMS 程式碼。輸入簡訊代碼後,您可以將驗證 ID 與簡訊代碼結合以建立新的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);
},
);
預設情況下,如果最近發送過新短信,Firebase 不會重新發送該短信。不過,您可以透過使用向forceResendingToken
參數重新傳送令牌重新呼叫verifyPhoneNumber
方法來重寫此行為。如果成功,將重新發送簡訊。
程式碼自動檢索逾時
在支援自動 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
在網路平台上,用戶可以透過輸入發送到所提供的電話號碼的簡訊代碼來確認他們可以使用電話來登入。為了提高安全性和防止垃圾郵件,使用者需要透過完成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 小部件顯示。用戶必須在發送簡訊代碼之前完成測試。完成後,您可以透過向解析的ConfirmationResult
回應上的confirm
方法提供簡訊代碼來登入使用者:
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,
));
您可以選擇透過自訂大小和主題參數來變更size
和theme
,如上所示。
也可以監聽事件,例如使用者是否已完成reCAPTCHA、reCAPTCHA是否已過期或拋出錯誤:
RecaptchaVerifier(
onSuccess: () => print('reCAPTCHA Completed!'),
onError: (FirebaseAuthException error) => print(error),
onExpired: () => print('reCAPTCHA Expired!'),
);
測試
Firebase 提供本地測試電話號碼的支援:
- 在 Firebase 控制台上,選擇「電話」驗證供應商,然後按一下「用於測試的電話號碼」下拉清單。
- 輸入新的電話號碼(例如
+44 7444 555666
)和測試代碼(例如123456
)。
如果向verifyPhoneNumber
或signInWithPhoneNumber
方法提供測試電話號碼,則實際上不會發送任何簡訊。您可以將測試程式碼直接提供給PhoneAuthProvider
或使用signInWithPhoneNumber
s 確認結果處理程序。