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