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

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

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

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

ตั้งค่า

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

  1. เปิดใช้โทรศัพท์เป็นวิธีการลงชื่อเข้าใช้ในคอนโซล Firebase
  2. Android: หากยังไม่ได้ตั้งค่าแฮช SHA-1 ของแอปในคอนโซล Firebase ให้ตั้งค่า ดูข้อมูลเกี่ยวกับการค้นหาแฮช SHA-1 ของแอปได้ที่การตรวจสอบสิทธิ์ไคลเอ็นต์
  3. iOS: ใน Xcode ให้เปิดใช้ข้อความ Push สำหรับโปรเจ็กต์และตรวจสอบว่าได้กำหนดค่าคีย์การตรวจสอบสิทธิ์ APNs ด้วย Firebase Cloud Messaging (FCM) แล้ว นอกจากนี้ คุณต้องเปิดใช้โหมดเบื้องหลังสำหรับการแจ้งเตือนจากระยะไกลด้วย หากต้องการดูคำอธิบายโดยละเอียดเกี่ยวกับขั้นตอนนี้ โปรดดูเอกสารประกอบ Firebase iOS Phone Auth
  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. verificationCompleted: การจัดการรหัส SMS โดยอัตโนมัติในอุปกรณ์ Android
  2. verificationFailed: จัดการเหตุการณ์ที่ล้มเหลว เช่น หมายเลขโทรศัพท์ไม่ถูกต้อง หรือโควต้า SMS เกิน
  3. codeSent: จัดการเมื่อ Firebase ส่งรหัสไปยังอุปกรณ์ ใช้เพื่อแจ้งให้ผู้ใช้ป้อนรหัส
  4. codeAutoRetrievalTimeout: จัดการการหมดเวลาเมื่อการจัดการรหัส SMS อัตโนมัติล้มเหลว

verificationCompleted

ระบบจะเรียกใช้ตัวแฮนเดิลนี้ในอุปกรณ์ 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);
  },
);

verificationFailed

หาก 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
  },
);

codeSent

เมื่อ Firebase ส่งรหัส SMS ไปยังอุปกรณ์ ระบบจะเรียกใช้แฮนเดิลเลอร์นี้พร้อมกับ verificationId และ resendToken (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 อีกครั้ง

codeAutoRetrievalTimeout

ในอุปกรณ์ 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');

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

การกำหนดค่า 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 แทนได้