如果您已升級至提供 Identity Platform 的 Firebase 驗證,可以為 Flutter 應用程式新增簡訊多重驗證機制。
多重驗證 (MFA) 可提升應用程式的安全性。攻擊者通常會竊取密碼及盜用社群媒體帳戶,但攔截簡訊則牽涉較為複雜的作業。
事前準備
啟用至少一個支援多重驗證的供應商。 所有供應商都支援 MFA,但電話驗證、匿名驗證和 Apple Game Center 除外。
確認應用程式會驗證使用者電子郵件。多重驗證需要電子郵件驗證。 這麼做可防止惡意人士使用不屬於自己的電子郵件註冊服務,然後新增第二個驗證因素,將真正的擁有者鎖在門外。
Android:如果您尚未在 Firebase 控制台中設定應用程式的 SHA-256 雜湊,請進行設定。如要瞭解如何找出應用程式的 SHA-256 雜湊,請參閱「驗證用戶端」。
iOS:在 Xcode 中為專案啟用推播通知,並確保 APNs 驗證金鑰已透過 Firebase 雲端通訊 (FCM) 設定。此外,您必須啟用遠端通知的背景模式。如需這個步驟的詳細說明,請參閱 Firebase iOS 電話號碼驗證說明文件。
網頁:請確認您已在 Firebase 主控台的「OAuth redirect domains」(OAuth 重新導向網域) 下方新增應用程式網域。
啟用多重驗證
在「進階」部分,啟用「簡訊多重驗證」。
您也應輸入要用來測試應用程式的電話號碼。 雖然這不是必要步驟,我們仍強烈建議您註冊測試電話號碼,以免在開發期間發生節流情形。
選擇註冊模式
您可以選擇應用程式是否需要多重驗證,以及如何和何時註冊使用者。常見的模式包括:
在註冊程序中,為使用者註冊第二個驗證因素。如果應用程式要求所有使用者都必須進行多重驗證,請使用這個方法。
在註冊期間提供可略過的選項,讓使用者註冊第二重驗證。如果應用程式希望使用者啟用多重驗證,但並非強制要求,或許會偏好採用這種做法。
讓使用者在帳戶或個人資料管理頁面新增第二個驗證要素,而非在註冊畫面新增。這樣可盡量減少註冊程序中的阻礙,同時仍為注重安全性的使用者提供多重驗證功能。
當使用者想存取安全性要求較高的功能時,逐步要求新增第二個驗證因素。
註冊第二個驗證步驟
如要為使用者註冊新的次要驗證因素,請按照下列步驟操作:
重新驗證使用者。
要求使用者輸入電話號碼。
取得使用者的多重驗證工作階段:
final multiFactorSession = await user.multiFactor.getSession();透過多重驗證工作階段和回呼驗證電話號碼:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: multiFactorSession, phoneNumber: phoneNumber, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // The SMS verification code has been sent to the provided phone number. // ... }, codeAutoRetrievalTimeout: (_) {}, );簡訊驗證碼傳送完畢後,請使用者驗證該驗證碼:
final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, );完成註冊:
await user.multiFactor.enroll( PhoneMultiFactorGenerator.getAssertion( credential, ), );
以下程式碼完整示範如何註冊第二個驗證因素:
final session = await user.multiFactor.getSession();
final auth = FirebaseAuth.instance;
await auth.verifyPhoneNumber(
multiFactorSession: session,
phoneNumber: phoneController.text,
verificationCompleted: (_) {},
verificationFailed: (_) {},
codeSent: (String verificationId, int? resendToken) async {
// See `firebase_auth` example app for a method of retrieving user's sms code:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
final smsCode = await getSmsCodeFromUser(context);
if (smsCode != null) {
// Create a PhoneAuthCredential with the code
final credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
try {
await user.multiFactor.enroll(
PhoneMultiFactorGenerator.getAssertion(
credential,
),
);
} on FirebaseAuthException catch (e) {
print(e.message);
}
}
},
codeAutoRetrievalTimeout: (_) {},
);
恭喜!您已成功為使用者註冊第二個驗證因素。
透過第二個驗證要素登入使用者
如要透過簡訊雙重驗證登入使用者,請按照下列步驟操作:
使用者的第一個驗證因素登入,然後擷取
FirebaseAuthMultiFactorException例外狀況。這個錯誤包含解析器,可用於取得使用者已註冊的第二個驗證因素。其中也包含基礎工作階段,證明使用者已透過主要驗證方法成功完成驗證。舉例來說,如果使用者第一個驗證因素是電子郵件地址和密碼:
try { await _auth.signInWithEmailAndPassword( email: emailController.text, password: passwordController.text, ); // User is not enrolled with a second factor and is successfully // signed in. // ... } on FirebaseAuthMultiFactorException catch (e) { // The user is a multi-factor user. Second factor challenge is required final resolver = e.resolver // ... }如果使用者已註冊多個次要驗證因素,請詢問要使用哪一個:
final session = e.resolver.session; final hint = e.resolver.hints[selectedHint];將驗證訊息連同提示和多重驗證工作階段傳送至使用者的手機:
await FirebaseAuth.instance.verifyPhoneNumber( multiFactorSession: session, multiFactorInfo: hint, verificationCompleted: (_) {}, verificationFailed: (_) {}, codeSent: (String verificationId, int? resendToken) async { // ... }, codeAutoRetrievalTimeout: (_) {}, );致電
resolver.resolveSignIn()完成二次驗證:final smsCode = await getSmsCodeFromUser(context); if (smsCode != null) { // Create a PhoneAuthCredential with the code final credential = PhoneAuthProvider.credential( verificationId: verificationId, smsCode: smsCode, ); try { await e.resolver.resolveSignIn( PhoneMultiFactorGenerator.getAssertion(credential) ); } on FirebaseAuthException catch (e) { print(e.message); } }
以下程式碼完整示範如何登入多重驗證使用者:
try {
await _auth.signInWithEmailAndPassword(
email: emailController.text,
password: passwordController.text,
);
} on FirebaseAuthMultiFactorException catch (e) {
setState(() {
error = '${e.message}';
});
final firstHint = e.resolver.hints.first;
if (firstHint is! PhoneMultiFactorInfo) {
return;
}
await FirebaseAuth.instance.verifyPhoneNumber(
multiFactorSession: e.resolver.session,
multiFactorInfo: firstHint,
verificationCompleted: (_) {},
verificationFailed: (_) {},
codeSent: (String verificationId, int? resendToken) async {
// See `firebase_auth` example app for a method of retrieving user's sms code:
// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591
final smsCode = await getSmsCodeFromUser(context);
if (smsCode != null) {
// Create a PhoneAuthCredential with the code
final credential = PhoneAuthProvider.credential(
verificationId: verificationId,
smsCode: smsCode,
);
try {
await e.resolver.resolveSignIn(
PhoneMultiFactorGenerator.getAssertion(
credential,
),
);
} on FirebaseAuthException catch (e) {
print(e.message);
}
}
},
codeAutoRetrievalTimeout: (_) {},
);
} catch (e) {
...
}
恭喜!您已成功使用多重驗證登入使用者。
後續步驟
- 使用 Admin SDK,以程式輔助的方式管理多重驗證使用者。