หากคุณอัปเกรดเป็น Firebase Authentication ด้วย Identity Platform แล้ว คุณสามารถเพิ่ม SMS Multi-Factor Authentication ให้กับแอป Flutter ของคุณได้
การตรวจสอบสิทธิ์แบบหลายปัจจัย (MFA) ช่วยเพิ่มความปลอดภัยให้กับแอปของคุณ แม้ว่าผู้โจมตีมักจะบุกรุกรหัสผ่านและบัญชีโซเชียล แต่การสกัดกั้นข้อความนั้นยากกว่า
ก่อนที่คุณจะเริ่ม
เปิดใช้งานผู้ให้บริการอย่างน้อยหนึ่งรายที่รองรับการรับรองความถูกต้องแบบหลายปัจจัย ผู้ให้บริการทุกรายรองรับ MFA ยกเว้น การตรวจสอบสิทธิ์ทางโทรศัพท์ การตรวจสอบแบบไม่เปิดเผยตัวตน และ Apple Game Center
ตรวจสอบให้แน่ใจว่าแอปของคุณกำลังยืนยันอีเมลของผู้ใช้ MFA กำหนดให้มีการยืนยันอีเมล วิธีนี้จะป้องกันไม่ให้ผู้ไม่ประสงค์ดีลงทะเบียนใช้บริการด้วยอีเมลที่พวกเขาไม่ได้เป็นเจ้าของ จากนั้นจึงล็อกเจ้าของที่แท้จริงออกด้วยการเพิ่มปัจจัยที่สอง
Android : หากคุณยังไม่ได้ตั้งค่าแฮช SHA-256 ของแอปใน คอนโซล Firebase ให้ดำเนินการดังกล่าว ดู การตรวจสอบสิทธิ์ไคลเอ็นต์ของคุณ สำหรับข้อมูลเกี่ยวกับการค้นหาแฮช SHA-256 ของแอปของคุณ
iOS : ใน Xcode ให้เปิดใช้งานการแจ้งเตือนแบบพุช สำหรับโปรเจ็กต์ของคุณ & ตรวจสอบให้แน่ใจว่าคีย์การตรวจสอบสิทธิ์ APN ของคุณได้ รับการกำหนดค่าด้วย Firebase Cloud Messaging (FCM) นอกจากนี้ คุณต้อง เปิดใช้งานโหมดเบื้องหลัง สำหรับการแจ้งเตือนระยะไกล หากต้องการดูคำอธิบายเชิงลึกของขั้นตอนนี้ โปรดดูเอกสาร Firebase iOS Phone Auth
เว็บ : ตรวจสอบให้แน่ใจว่าคุณได้เพิ่มโดเมนแอปพลิเคชันของคุณบน คอนโซล Firebase ภายใต้ โดเมนการเปลี่ยนเส้นทาง OAuth
การเปิดใช้งานการรับรองความถูกต้องแบบหลายปัจจัย
เปิดหน้า การตรวจสอบสิทธิ์ > วิธีการลงชื่อเข้าใช้ ของคอนโซล Firebase
ในส่วน ขั้นสูง ให้เปิดใช้งาน SMS Multi-factor Authentication
คุณควรป้อนหมายเลขโทรศัพท์ที่จะใช้ทดสอบแอปของคุณด้วย แม้ว่าจะเป็นทางเลือก แต่ขอแนะนำอย่างยิ่งให้ลงทะเบียนหมายเลขโทรศัพท์ทดสอบเพื่อหลีกเลี่ยงการควบคุมปริมาณระหว่างการพัฒนา
หากคุณยังไม่ได้อนุญาตโดเมนของแอปของคุณ ให้เพิ่มลงในรายการอนุญาตบนหน้า การตรวจสอบสิทธิ์ > การตั้งค่า ของคอนโซล Firebase
การเลือกรูปแบบการลงทะเบียน
คุณสามารถเลือกได้ว่าแอปของคุณต้องมีการตรวจสอบสิทธิ์แบบหลายปัจจัยหรือไม่ รวมถึงจะลงทะเบียนผู้ใช้อย่างไรและเมื่อใด รูปแบบทั่วไปบางประการ ได้แก่:
ลงทะเบียนปัจจัยที่สองของผู้ใช้เป็นส่วนหนึ่งของการลงทะเบียน ใช้วิธีนี้หากแอปของคุณต้องมีการตรวจสอบสิทธิ์แบบหลายปัจจัยสำหรับผู้ใช้ทั้งหมด
เสนอตัวเลือกที่ข้ามได้เพื่อลงทะเบียนปัจจัยที่ 2 ระหว่างการลงทะเบียน แอพที่ต้องการสนับสนุน แต่ไม่จำเป็นต้องมีการตรวจสอบสิทธิ์แบบหลายปัจจัยอาจชอบวิธีนี้
ให้ความสามารถในการเพิ่มปัจจัยที่สองจากบัญชีของผู้ใช้หรือหน้าการจัดการโปรไฟล์ แทนหน้าจอการลงทะเบียน สิ่งนี้จะช่วยลดความขัดแย้งระหว่างขั้นตอนการลงทะเบียน ในขณะที่ยังคงให้การรับรองความถูกต้องแบบหลายปัจจัยสำหรับผู้ใช้ที่คำนึงถึงความปลอดภัย
ต้องเพิ่มปัจจัยที่สองทีละน้อยเมื่อผู้ใช้ต้องการเข้าถึงคุณลักษณะที่มีข้อกำหนดด้านความปลอดภัยที่เพิ่มขึ้น
การลงทะเบียนปัจจัยที่สอง
หากต้องการลงทะเบียนปัจจัยรองใหม่สำหรับผู้ใช้:
ตรวจสอบสิทธิ์ผู้ใช้อีกครั้ง
ขอให้ผู้ใช้ป้อนหมายเลขโทรศัพท์ของตน
รับเซสชันแบบหลายปัจจัยสำหรับผู้ใช้:
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: (_) {}, );
เมื่อส่งรหัส SMS แล้ว ให้ขอให้ผู้ใช้ยืนยันรหัส:
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: (_) {},
);
ยินดีด้วย! คุณลงทะเบียนปัจจัยการรับรองความถูกต้องที่สองสำหรับผู้ใช้สำเร็จแล้ว
การลงชื่อเข้าใช้ผู้ใช้ด้วยปัจจัยที่ 2
หากต้องการลงชื่อเข้าใช้ผู้ใช้ด้วยการยืนยัน SMS แบบสองปัจจัย:
ลงชื่อเข้าใช้ผู้ใช้ด้วยปัจจัยแรก จากนั้นตรวจสอบข้อยกเว้น
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