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

การตรวจสอบสิทธิ์ทางโทรศัพท์ช่วยให้ผู้ใช้ลงชื่อเข้าใช้ 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
  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 แทนได้