如果您已透過 Identity Platform 升級至 Firebase 驗證, 您可以在 Flutter 應用程式中新增簡訊多重驗證。
多重驗證 (MFA) 可提升應用程式的安全性。雖然攻擊者 經常會竊取密碼和社群媒體帳戶、攔截簡訊, 變得更困難
事前準備
請至少啟用一個支援多重驗證的供應商。 每個供應商都支援多重驗證,但電話驗證、匿名驗證和 Apple Game Center。
確認應用程式正在驗證使用者的電子郵件地址。MFA 需要電子郵件驗證。 這可防止惡意人士利用電子郵件註冊服務 成為非擁有人,進而鎖定真正的擁有者 。
Android:如果您尚未在 Firebase 控制台可完成這項操作。 請參閱驗證用戶端 瞭解如何找出應用程式的 SHA-256 雜湊。
iOS:在 Xcode 中,為專案啟用推播通知,並確保 您的 APN 驗證金鑰已透過 Firebase 雲端通訊 (FCM) 進行設定。此外,您也必須遵守 啟用遠端通知的背景模式。 如要深入瞭解這個步驟,請參閱 Firebase iOS 手機驗證說明文件。
網路:請確認您已在 Firebase 主控台的 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/master/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/master/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 編寫程式