เพิ่มการตรวจสอบสิทธิ์แบบหลายปัจจัยในแอป Flutter

หากคุณอัปเกรดเป็นการตรวจสอบสิทธิ์ Firebase ด้วย Identity Platform แล้ว คุณจะเพิ่มการตรวจสอบสิทธิ์แบบหลายปัจจัยทาง SMS ในแอป Flutter ได้

การตรวจสอบสิทธิ์แบบหลายปัจจัย (MFA) จะช่วยเพิ่มความปลอดภัยให้กับแอปของคุณ ขณะที่ผู้โจมตี มักเจาะรหัสผ่านและบัญชีโซเชียล การดักฟังข้อความจึงเป็น ยากขึ้น

ก่อนเริ่มต้น

  1. เปิดใช้ผู้ให้บริการอย่างน้อย 1 รายที่รองรับการตรวจสอบสิทธิ์แบบหลายปัจจัย ผู้ให้บริการทุกรายรองรับ MFA ยกเว้นการตรวจสอบสิทธิ์ทางโทรศัพท์ การตรวจสอบสิทธิ์แบบไม่ระบุชื่อ และ Apple Game Center

  2. ตรวจสอบว่าแอปกำลังยืนยันอีเมลผู้ใช้ MFA ต้องมีการยืนยันอีเมล วิธีนี้จะป้องกันไม่ให้ผู้ไม่ประสงค์ดีลงทะเบียนใช้บริการด้วยอีเมล ไม่ได้เป็นเจ้าของ แล้วปิดกั้นเจ้าของที่แท้จริงด้วยการเพิ่ม ปัจจัย

  3. Android: หากคุณยังไม่ได้ตั้งค่าแฮช SHA-256 ของแอปใน คอนโซล Firebase ได้เลย ดูการตรวจสอบสิทธิ์ไคลเอ็นต์ เพื่อหาข้อมูลเกี่ยวกับการค้นหาแฮช SHA-256 ของแอป

  4. iOS: ใน Xcode ให้เปิดใช้ข้อความ Push สําหรับโปรเจ็กต์และ ตรวจสอบ คีย์การตรวจสอบสิทธิ์ APN ของคุณกำหนดค่าด้วย Firebase Cloud Messaging (FCM) นอกจากนี้ คุณต้อง เปิดใช้โหมดพื้นหลังสำหรับการแจ้งเตือนระยะไกล หากต้องการดูคำอธิบายโดยละเอียดของขั้นตอนนี้ โปรดดูเอกสารการตรวจสอบสิทธิ์โทรศัพท์บน iOS ของ Firebase

  5. เว็บ: ตรวจสอบว่าได้เพิ่มโดเมนแอปพลิเคชันในคอนโซล Firebase ในส่วน โดเมนการเปลี่ยนเส้นทาง OAuth

การเปิดใช้การตรวจสอบสิทธิ์แบบหลายปัจจัย

  1. เปิด Authentication > วิธีการลงชื่อเข้าใช้ ของคอนโซล Firebase

  2. ในส่วนขั้นสูง ให้เปิดใช้การตรวจสอบสิทธิ์แบบหลายปัจจัยทาง SMS

    และควรป้อนหมายเลขโทรศัพท์ที่จะใช้ทดสอบแอปด้วย เราขอแนะนำเป็นอย่างยิ่งให้ลงทะเบียนหมายเลขโทรศัพท์ทดสอบแม้ว่าจะไม่บังคับ ให้หลีกเลี่ยงการควบคุมในระหว่างการพัฒนา

  3. หากยังไม่ได้ให้สิทธิ์โดเมนของแอป ให้เพิ่มโดเมนลงในอนุญาต ใน การตรวจสอบสิทธิ์ > การตั้งค่า ของคอนโซล Firebase

การเลือกรูปแบบการลงทะเบียน

คุณเลือกได้ว่าจะให้แอปต้องใช้การตรวจสอบสิทธิ์แบบหลายปัจจัยหรือไม่ รวมถึงวิธี และกรณีที่ควรลงทะเบียนผู้ใช้ รูปแบบที่พบบ่อยบางส่วน ได้แก่

  • ลงทะเบียนปัจจัยที่ 2 ของผู้ใช้ซึ่งเป็นส่วนหนึ่งของการลงทะเบียน ใช้ร่างคำตอบนี้ หากแอปของคุณต้องตรวจสอบสิทธิ์แบบหลายปัจจัยสำหรับผู้ใช้ทั้งหมด

  • เสนอตัวเลือกที่ข้ามได้เพื่อลงทะเบียนปัจจัยที่ 2 ระหว่างการลงทะเบียน แอป ที่ต้องการกระตุ้นการตรวจสอบสิทธิ์แบบหลายปัจจัย แต่ไม่บังคับ ต้องการวิธีการนี้

  • มอบความสามารถในการเพิ่มปัจจัยที่ 2 จากบัญชีหรือโปรไฟล์ของผู้ใช้ หน้าการจัดการ แทนที่จะเป็นหน้าจอลงชื่อสมัครใช้ ซึ่งจะช่วยลดการติดขัดในระหว่าง กระบวนการลงทะเบียน ขณะที่ยังทำการตรวจสอบสิทธิ์แบบหลายปัจจัย พร้อมใช้งานสำหรับผู้ใช้ที่มีความละเอียดอ่อนด้านความปลอดภัย

  • ต้องเพิ่มปัจจัยที่ 2 เพิ่มเมื่อผู้ใช้ต้องการเข้าถึง ที่มีข้อกำหนดด้านความปลอดภัยที่เพิ่มขึ้น

การลงทะเบียนปัจจัยที่ 2

วิธีลงทะเบียนปัจจัยรองใหม่สำหรับผู้ใช้

  1. ตรวจสอบสิทธิ์ผู้ใช้อีกครั้ง

  2. ขอให้ผู้ใช้ป้อนหมายเลขโทรศัพท์

  3. รับเซสชันแบบหลายปัจจัยสำหรับผู้ใช้

    final multiFactorSession = await user.multiFactor.getSession();
  4. ยืนยันหมายเลขโทรศัพท์ด้วยเซสชันแบบหลายปัจจัยและการติดต่อกลับ โดยทำดังนี้

    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
    : (_) {},
    );
  5. เมื่อส่งรหัส SMS แล้ว ให้ผู้ใช้ยืนยันรหัสโดยทำดังนี้

    final credential = PhoneAuthProvider.credential(
      verificationId
    : verificationId,
      smsCode
    : smsCode,
    );
  6. ดำเนินการลงทะเบียนให้เสร็จสิ้น

    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/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 แบบ 2 ปัจจัย

  1. ให้ผู้ใช้ลงชื่อเข้าใช้ด้วยปัจจัยแรก จากนั้นให้ตรวจจับ ข้อยกเว้น 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
     
    // ...
    }
  2. หากผู้ใช้ลงทะเบียนปัจจัยรองไว้หลายรายการ ให้ถามผู้ใช้ว่าปัจจัยใด วิธีใช้

    final session = e.resolver.session;

    final hint = e.resolver.hints[selectedHint];
  3. ส่งข้อความยืนยันไปยังโทรศัพท์ของผู้ใช้พร้อมคำแนะนำและ เซสชันแบบหลายปัจจัย:

    await FirebaseAuth.instance.verifyPhoneNumber(
      multiFactorSession
    : session,
      multiFactorInfo
    : hint,
      verificationCompleted
    : (_) {},
      verificationFailed
    : (_) {},
      codeSent
    : (String verificationId, int? resendToken) async {
       
    // ...
     
    },
      codeAutoRetrievalTimeout
    : (_) {},
    );
  4. โทรติดต่อ 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) {
 
...
}

ยินดีด้วย คุณลงชื่อเข้าใช้ผู้ใช้ด้วยการตรวจสอบสิทธิ์แบบหลายปัจจัยสำเร็จแล้ว การตรวจสอบสิทธิ์

ขั้นตอนถัดไป