การตรวจสอบสิทธิ์ทางโทรศัพท์

การตรวจสอบสิทธิ์ทางโทรศัพท์ช่วยให้ผู้ใช้ลงชื่อเข้าใช้ Firebase ด้วยโทรศัพท์เป็น Authenticator ได้ ส่งข้อความ SMS แล้ว ให้แก่ผู้ใช้ (โดยใช้หมายเลขโทรศัพท์ที่ให้ไว้) ซึ่งมีรหัสที่ไม่ซ้ำกัน เมื่อให้สิทธิ์รหัสแล้ว ผู้ใช้จะลงนามได้ ไปยัง Firebase

Google จะส่งและจัดเก็บหมายเลขโทรศัพท์ที่ผู้ใช้ปลายทางให้สำหรับการตรวจสอบสิทธิ์ไว้เพื่อปรับปรุงจดหมายขยะและการละเมิด ในบริการของ Google ซึ่งรวมถึงแต่ไม่จำกัดเพียง Firebase นักพัฒนาแอปควรตรวจสอบว่าตนเองมี ความยินยอมของผู้ใช้ปลายทางที่เหมาะสมก่อนใช้การลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์การตรวจสอบสิทธิ์ Firebase ด้วย service.authentication

การตรวจสอบสิทธิ์ทางโทรศัพท์ของ Firebase ไม่ได้รับการสนับสนุนในบางประเทศ โปรดดูคำถามที่พบบ่อยสำหรับข้อมูลเพิ่มเติม

ตั้งค่า

ก่อนที่จะเริ่มต้นด้วยการตรวจสอบสิทธิ์ทางโทรศัพท์ โปรดตรวจสอบว่าคุณได้ทำตามขั้นตอนต่อไปนี้

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

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

การใช้งาน

Firebase Authentication SDK สำหรับ Flutter มี 2 วิธีในการลงชื่อเข้าใช้ให้ผู้ใช้ด้วยหมายเลขโทรศัพท์ แพลตฟอร์มดั้งเดิม (เช่น Android และ iOS) มี ฟังก์ชันที่แตกต่างกันในการตรวจสอบความถูกต้องของหมายเลขโทรศัพท์เมื่อเทียบกับเว็บ ดังนั้น 2 วิธีนี้จึงมีให้บริการสำหรับแต่ละแพลตฟอร์มโดยเฉพาะ

  • แพลตฟอร์มดั้งเดิม: verifyPhoneNumber
  • แพลตฟอร์มเว็บ: signInWithPhoneNumber

เนทีฟ: verifyPhoneNumber

สำหรับแพลตฟอร์มเนทีฟ หมายเลขโทรศัพท์ของผู้ใช้จะต้องได้รับการยืนยันก่อน จากนั้นจึงจะลงชื่อเข้าใช้หรือลิงก์บัญชีของตนกับ PhoneAuthCredential

ก่อนอื่น คุณต้องแจ้งให้ผู้ใช้ทราบหมายเลขโทรศัพท์ เมื่อระบุแล้ว ให้เรียกใช้เมธอด verifyPhoneNumber():

await FirebaseAuth.instance.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) {},
  verificationFailed: (FirebaseAuthException e) {},
  codeSent: (String verificationId, int? resendToken) {},
  codeAutoRetrievalTimeout: (String verificationId) {},
);

มี Callback แยกต่างหาก 4 รายการที่คุณจะต้องจัดการ แต่ละรายการจะกำหนดวิธีที่คุณอัปเดต UI ของแอปพลิเคชัน ดังนี้

  1. verificationFinish: จัดการรหัส SMS ในอุปกรณ์ Android โดยอัตโนมัติ
  2. verificationFailed: จัดการกับเหตุการณ์ที่ล้มเหลว เช่น หมายเลขโทรศัพท์ไม่ถูกต้อง หรือการใช้ SMS เกินโควต้า
  3. codeSent: จัดการเมื่อมีการส่งรหัสจาก Firebase ไปยังอุปกรณ์ เพื่อแจ้งให้ผู้ใช้ป้อนรหัส
  4. codeAutoRetrievalระยะหมดเวลา: จัดการระยะหมดเวลาเมื่อจัดการโค้ด SMS อัตโนมัติไม่สำเร็จ

การยืนยันเสร็จสมบูรณ์

ระบบจะเรียกใช้เครื่องจัดการนี้เฉพาะในอุปกรณ์ Android ที่รองรับการแปลงโค้ด SMS อัตโนมัติ

เมื่อส่งรหัส SMS ไปยังอุปกรณ์ Android จะยืนยันรหัส SMS โดยอัตโนมัติโดยไม่มี การกำหนดให้ผู้ใช้ป้อนรหัสด้วยตนเอง หากเหตุการณ์นี้เกิดขึ้น ระบบจะระบุ PhoneAuthCredential โดยอัตโนมัติ ซึ่งสามารถ ใช้เพื่อลงชื่อเข้าใช้หรือลิงก์หมายเลขโทรศัพท์ของผู้ใช้

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationCompleted: (PhoneAuthCredential credential) async {
    // ANDROID ONLY!

    // Sign the user in (or link) with the auto-generated credential
    await auth.signInWithCredential(credential);
  },
);

การยืนยันล้มเหลว

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

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  verificationFailed: (FirebaseAuthException e) {
    if (e.code == 'invalid-phone-number') {
      print('The provided phone number is not valid.');
    }

    // Handle other errors
  },
);

ส่งรหัสแล้ว

เมื่อ Firebase ส่งรหัส SMS ไปยังอุปกรณ์ เครื่องจัดการนี้จะทำงานด้วย verificationId และ resendToken (A resendToken ใช้ได้กับอุปกรณ์ Android เท่านั้น อุปกรณ์ iOS จะแสดงผลค่า null เสมอ)

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

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  codeSent: (String verificationId, int? resendToken) async {
    // Update the UI - wait for the user to enter the SMS code
    String smsCode = 'xxxx';

    // Create a PhoneAuthCredential with the code
    PhoneAuthCredential credential = PhoneAuthProvider.credential(verificationId: verificationId, smsCode: smsCode);

    // Sign the user in (or link) with the credential
    await auth.signInWithCredential(credential);
  },
);

โดยค่าเริ่มต้น Firebase จะไม่ส่งข้อความ SMS ใหม่หากเพิ่งส่งไปเมื่อเร็วๆ นี้ อย่างไรก็ตาม คุณลบล้างลักษณะการทำงานนี้ได้ โดยการเรียกคืนเมธอด verifyPhoneNumber ด้วยโทเค็นการส่งซ้ำไปยังอาร์กิวเมนต์ forceResendingToken หากสำเร็จ ระบบจะส่งข้อความ SMS อีกครั้ง

codeAutoRetrievalระยะหมดเวลา

ในอุปกรณ์ Android ที่รองรับการแปลงรหัส SMS อัตโนมัติ ระบบจะเรียกใช้เครื่องจัดการนี้หากอุปกรณ์ไม่ทำให้โดยอัตโนมัติ แก้ปัญหาข้อความ SMS ภายในระยะเวลาที่กำหนด เมื่อพ้นกรอบเวลาแล้ว อุปกรณ์จะไม่พยายามแก้ไขอีกต่อไป ข้อความขาเข้าทั้งหมด

โดยค่าเริ่มต้น อุปกรณ์จะรอ 30 วินาที แต่คุณสามารถปรับแต่งได้ด้วยอาร์กิวเมนต์ timeout ดังนี้

FirebaseAuth auth = FirebaseAuth.instance;

await auth.verifyPhoneNumber(
  phoneNumber: '+44 7123 123 456',
  timeout: const Duration(seconds: 60),
  codeAutoRetrievalTimeout: (String verificationId) {
    // Auto-resolution timed out...
  },
);

เว็บ: signInWithPhoneNumber

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

Firebase Authentication SDK สำหรับ Flutter จะจัดการวิดเจ็ต reCAPTCHA แบบใช้งานได้ทันทีโดยค่าเริ่มต้น แต่จะควบคุมวิธีแสดงและกำหนดค่าได้หากจำเป็น โทรหาเมธอด signInWithPhoneNumber ด้วยหมายเลขโทรศัพท์เพื่อเริ่มต้นใช้งาน

FirebaseAuth auth = FirebaseAuth.instance;

// Wait for the user to complete the reCAPTCHA & for an SMS code to be sent.
ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456');

การเรียกเมธอดจะเรียกให้วิดเจ็ต reCAPTCHA แสดงขึ้นมาก่อน ผู้ใช้ต้องดำเนินการตาม ทดสอบก่อนที่จะส่งรหัส SMS เมื่อดำเนินการเสร็จแล้ว คุณสามารถลงชื่อเข้าใช้ให้ผู้ใช้โดยระบุ รหัส SMS ไปยังเมธอด confirm ในการตอบ ConfirmationResult ที่แก้ไขแล้ว:

UserCredential userCredential = await confirmationResult.confirm('123456');

การลงชื่อเข้าใช้ที่สำเร็จจะทริกเกอร์ Listener สถานะการตรวจสอบสิทธิ์เช่นเดียวกับขั้นตอนการลงชื่อเข้าใช้อื่นๆ ที่คุณสมัครไว้ตลอดการสมัคร

การกำหนดค่า reCAPTCHA

วิดเจ็ต reCAPTCHA เป็นขั้นตอนที่มีการจัดการครบวงจรซึ่งมอบความปลอดภัยให้กับเว็บแอปพลิเคชัน

อาร์กิวเมนต์ที่ 2 ของ signInWithPhoneNumber จะยอมรับอินสแตนซ์ RecaptchaVerifier ที่ไม่บังคับซึ่งใช้งานได้ เพื่อจัดการวิดเจ็ต โดยค่าเริ่มต้น วิดเจ็ตจะแสดงผลเป็นวิดเจ็ตที่มองไม่เห็นเมื่อมีการเรียกใช้ขั้นตอนการลงชื่อเข้าใช้ แท็ก "ซ่อนตัว" จะแสดงเป็นโมดัลแบบเต็มหน้าที่ด้านบนของแอปพลิเคชัน

แต่สามารถแสดงวิดเจ็ตในบรรทัดที่ผู้ใช้ต้องกดอย่างชัดแจ้งเพื่อยืนยันตนเอง

หากต้องการเพิ่มวิดเจ็ตในหน้า ให้ระบุรหัสองค์ประกอบ DOM ลงในอาร์กิวเมนต์ container ของอินสแตนซ์ RecaptchaVerifier องค์ประกอบดังกล่าวต้องมีอยู่และว่างเปล่า ไม่เช่นนั้นจะเกิดข้อผิดพลาด หากไม่ระบุอาร์กิวเมนต์ container วิดเจ็ตจะแสดงผลเป็น "ไม่แสดง"

ConfirmationResult confirmationResult = await auth.signInWithPhoneNumber('+44 7123 123 456', RecaptchaVerifier(
  container: 'recaptcha',
  size: RecaptchaVerifierSize.compact,
  theme: RecaptchaVerifierTheme.dark,
));

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

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

RecaptchaVerifier(
  onSuccess: () => print('reCAPTCHA Completed!'),
  onError: (FirebaseAuthException error) => print(error),
  onExpired: () => print('reCAPTCHA Expired!'),
);

การทดสอบ

Firebase รองรับการทดสอบหมายเลขโทรศัพท์ในพื้นที่ ดังนี้

  1. ในคอนโซล Firebase ให้เลือก "โทรศัพท์" ผู้ให้บริการตรวจสอบสิทธิ์ และคลิก "หมายเลขโทรศัพท์สำหรับการทดสอบ" แบบเลื่อนลง
  2. ป้อนหมายเลขโทรศัพท์ใหม่ (เช่น +44 7444 555666) และรหัสทดสอบ (เช่น 123456)

หากระบุหมายเลขโทรศัพท์สำหรับทดสอบไปยังเมธอด verifyPhoneNumber หรือ signInWithPhoneNumber ระบบจะไม่ส่ง SMS จริงๆ คุณ สามารถให้รหัสการทดสอบโดยตรงไปยัง PhoneAuthProvider หรือด้วยเครื่องจัดการผลลัพธ์การยืนยัน signInWithPhoneNumber