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

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

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

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

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

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

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

การใช้กลุ่มผู้ใช้หลายกลุ่ม

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

  1. เลือกกลุ่มผู้ใช้ที่ต้องการจัดการในคอนโซล GCP

  2. ในโค้ด ให้ตั้งค่าช่อง tenantId บนอินสแตนซ์ Auth เป็นรหัสกลุ่มผู้ใช้ เช่น

    Web Modular API

    import { getAuth } from "firebase/auth";
    
    const auth = getAuth(app);
    auth.tenantId = "myTenantId1";
    

    API ที่ใช้เนมสเปซในเว็บ

    firebase.auth().tenantId = 'myTenantId1';
    

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

  1. เปิดหน้าการตรวจสอบสิทธิ์ > วิธีการลงชื่อเข้าใช้ ของคอนโซล Firebase

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

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

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

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

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

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

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

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

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

การตั้งค่าเครื่องมือยืนยัน reCAPTCHA

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

คุณไม่จำเป็นต้องตั้งค่าไคลเอ็นต์ reCAPTCHA ด้วยตนเอง เพราะออบเจ็กต์ RecaptchaVerifier ของ SDK ของไคลเอ็นต์จะสร้างและเริ่มต้นคีย์และรหัสลับไคลเอ็นต์ที่จำเป็นโดยอัตโนมัติ

การใช้ reCAPTCHA ที่ไม่แสดง

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

Web Modular API

import { RecaptchaVerifier } from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier("sign-in-button", {
    "size": "invisible",
    "callback": function(response) {
        // reCAPTCHA solved, you can proceed with
        // phoneAuthProvider.verifyPhoneNumber(...).
        onSolvedRecaptcha();
    }
}, auth);

API ที่ใช้เนมสเปซในเว็บ

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
'size': 'invisible',
'callback': function(response) {
  // reCAPTCHA solved, you can proceed with phoneAuthProvider.verifyPhoneNumber(...).
  onSolvedRecaptcha();
}
});

การใช้วิดเจ็ต reCAPTCHA

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

Web Modular API

import { RecaptchaVerifier } from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier(
    "recaptcha-container",

    // Optional reCAPTCHA parameters.
    {
      "size": "normal",
      "callback": function(response) {
        // reCAPTCHA solved, you can proceed with
        // phoneAuthProvider.verifyPhoneNumber(...).
        onSolvedRecaptcha();
      },
      "expired-callback": function() {
        // Response expired. Ask user to solve reCAPTCHA again.
        // ...
      }
    }, auth
);

API ที่ใช้เนมสเปซในเว็บ

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier(
  'recaptcha-container',
  // Optional reCAPTCHA parameters.
  {
    'size': 'normal',
    'callback': function(response) {
      // reCAPTCHA solved, you can proceed with phoneAuthProvider.verifyPhoneNumber(...).
      // ...
      onSolvedRecaptcha();
    },
    'expired-callback': function() {
      // Response expired. Ask user to solve reCAPTCHA again.
      // ...
    }
  });

การแสดงผล reCAPTCHA ล่วงหน้า

หรือคุณจะแสดงผล reCAPTCHA ล่วงหน้าก่อนเริ่มการลงทะเบียนแบบ 2 ปัจจัยก็ได้ ดังนี้

Web Modular API

recaptchaVerifier.render()
    .then(function (widgetId) {
        window.recaptchaWidgetId = widgetId;
    });

API ที่ใช้เนมสเปซในเว็บ

recaptchaVerifier.render()
  .then(function(widgetId) {
    window.recaptchaWidgetId = widgetId;
  });

หลังจากแก้ปัญหา render() แล้ว คุณจะได้รับรหัสวิดเจ็ตของ reCAPTCHA ซึ่งคุณจะใช้เรียก reCAPTCHA API ได้โดยทำดังนี้

var recaptchaResponse = grecaptcha.getResponse(window.recaptchaWidgetId);

RecaptchaVerifier ย่อตรรกะนี้ออกไปโดยใช้เมธอดยืนยัน คุณจึงไม่ต้องจัดการตัวแปร grecaptcha โดยตรง

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

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

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

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

  3. เริ่มต้นเครื่องมือยืนยัน reCAPTCHA ตามที่แสดงไว้ในส่วนก่อนหน้า โปรดข้ามขั้นตอนนี้หากมีการกำหนดค่าอินสแตนซ์ reCAPTCHAtchaVerifier แล้ว

    Web Modular API

    import { RecaptchaVerifier } from "firebase/auth";
    
    const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
    

    API ที่ใช้เนมสเปซในเว็บ

    var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
    
  4. รับเซสชันแบบหลายปัจจัยสำหรับผู้ใช้

    Web Modular API

    import { multiFactor } from "firebase/auth";
    
    multiFactor(user).getSession().then(function (multiFactorSession) {
        // ...
    });
    

    API ที่ใช้เนมสเปซในเว็บ

    user.multiFactor.getSession().then(function(multiFactorSession) {
      // ...
    })
    
  5. เริ่มต้นออบเจ็กต์ PhoneInfoOptions ด้วยหมายเลขโทรศัพท์ของผู้ใช้และเซสชันแบบหลายปัจจัย ดังนี้

    Web Modular API

    // Specify the phone number and pass the MFA session.
    const phoneInfoOptions = {
      phoneNumber: phoneNumber,
      session: multiFactorSession
    };
    

    API ที่ใช้เนมสเปซในเว็บ

    // Specify the phone number and pass the MFA session.
    var phoneInfoOptions = {
      phoneNumber: phoneNumber,
      session: multiFactorSession
    };
    
  6. ส่งข้อความยืนยันไปยังโทรศัพท์ของผู้ใช้:

    Web Modular API

    import { PhoneAuthProvider } from "firebase/auth";
    
    const phoneAuthProvider = new PhoneAuthProvider(auth);
    phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
        .then(function (verificationId) {
            // verificationId will be needed to complete enrollment.
        });
    

    API ที่ใช้เนมสเปซในเว็บ

    var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
    // Send SMS verification code.
    return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
      .then(function(verificationId) {
        // verificationId will be needed for enrollment completion.
      })
    

    ถือเป็นแนวทางปฏิบัติแนะนำแม้ว่าจะไม่จำเป็น แต่ควรแจ้งผู้ใช้ล่วงหน้าว่าจะได้รับข้อความ SMS โดยมีค่าบริการมาตรฐาน

  7. หากขอไม่สำเร็จ ให้รีเซ็ต reCAPTCHA แล้วทำขั้นตอนก่อนหน้าซ้ำเพื่อให้ผู้ใช้ลองอีกครั้ง โปรดทราบว่า verifyPhoneNumber() จะรีเซ็ต reCAPTCHA โดยอัตโนมัติเมื่อเกิดข้อผิดพลาด เนื่องจากโทเค็น reCAPTCHA ใช้เพียงครั้งเดียวเท่านั้น

    Web Modular API

    recaptchaVerifier.clear();
    

    API ที่ใช้เนมสเปซในเว็บ

    recaptchaVerifier.clear();
    
  8. เมื่อส่งรหัส SMS แล้ว ให้ผู้ใช้ยืนยันรหัสโดยทำดังนี้

    Web Modular API

    // Ask user for the verification code. Then:
    const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
    

    API ที่ใช้เนมสเปซในเว็บ

    // Ask user for the verification code. Then:
    var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
    
  9. เริ่มต้นออบเจ็กต์ MultiFactorAssertion ด้วย PhoneAuthCredential ดังนี้

    Web Modular API

    import { PhoneMultiFactorGenerator } from "firebase/auth";
    
    const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
    

    API ที่ใช้เนมสเปซในเว็บ

    var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
    
  10. ลงทะเบียนให้เสร็จสิ้น หรือจะระบุชื่อที่แสดงสำหรับปัจจัยที่ 2 ก็ได้ วิธีนี้มีประโยชน์สำหรับผู้ใช้ที่มีปัจจัยที่ 2 หลายตัว เนื่องจากหมายเลขโทรศัพท์จะถูกมาสก์ระหว่างขั้นตอนการตรวจสอบสิทธิ์ (เช่น +1******1234)

    Web Modular API

    // Complete enrollment. This will update the underlying tokens
    // and trigger ID token change listener.
    multiFactor(user).enroll(multiFactorAssertion, "My personal phone number");
    

    API ที่ใช้เนมสเปซในเว็บ

    // Complete enrollment. This will update the underlying tokens
    // and trigger ID token change listener.
    user.multiFactor.enroll(multiFactorAssertion, 'My personal phone number');
    

โค้ดด้านล่างแสดงตัวอย่างทั้งหมดของการลงทะเบียนปัจจัยที่ 2

Web Modular API

import {
    multiFactor, PhoneAuthProvider, PhoneMultiFactorGenerator,
    RecaptchaVerifier
} from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
multiFactor(user).getSession()
    .then(function (multiFactorSession) {
        // Specify the phone number and pass the MFA session.
        const phoneInfoOptions = {
            phoneNumber: phoneNumber,
            session: multiFactorSession
        };

        const phoneAuthProvider = new PhoneAuthProvider(auth);

        // Send SMS verification code.
        return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier);
    }).then(function (verificationId) {
        // Ask user for the verification code. Then:
        const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
        const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);

        // Complete enrollment.
        return multiFactor(user).enroll(multiFactorAssertion, mfaDisplayName);
    });

API ที่ใช้เนมสเปซในเว็บ

var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
user.multiFactor.getSession().then(function(multiFactorSession) {
  // Specify the phone number and pass the MFA session.
  var phoneInfoOptions = {
    phoneNumber: phoneNumber,
    session: multiFactorSession
  };
  var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
  // Send SMS verification code.
  return phoneAuthProvider.verifyPhoneNumber(
      phoneInfoOptions, recaptchaVerifier);
})
.then(function(verificationId) {
  // Ask user for the verification code.
  var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
  var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
  // Complete enrollment.
  return user.multiFactor.enroll(multiFactorAssertion, mfaDisplayName);
});

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

การลงชื่อเข้าใช้ด้วยปัจจัยที่ 2 สำหรับผู้ใช้

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

  1. ให้ผู้ใช้ลงชื่อเข้าใช้ด้วยปัจจัยแรก จากนั้นตรวจจับข้อผิดพลาด auth/multi-factor-auth-required ข้อผิดพลาดนี้มีตัวแก้ปัญหา คำแนะนำเกี่ยวกับปัจจัยที่ 2 ที่ลงทะเบียน และเซสชันที่สำคัญซึ่งพิสูจน์ว่าผู้ใช้ตรวจสอบสิทธิ์ด้วยปัจจัยแรกสำเร็จแล้ว

    เช่น หากปัจจัยแรกของผู้ใช้คืออีเมลและรหัสผ่าน จะเกิดผลดังนี้

    Web Modular API

    import { getAuth, getMultiFactorResolver} from "firebase/auth";
    
    const auth = getAuth();
    signInWithEmailAndPassword(auth, email, password)
        .then(function (userCredential) {
            // User successfully signed in and is not enrolled with a second factor.
        })
        .catch(function (error) {
            if (error.code == 'auth/multi-factor-auth-required') {
                // The user is a multi-factor user. Second factor challenge is required.
                resolver = getMultiFactorResolver(auth, error);
                // ...
            } else if (error.code == 'auth/wrong-password') {
                // Handle other errors such as wrong password.
            }
    });
    

    API ที่ใช้เนมสเปซในเว็บ

    firebase.auth().signInWithEmailAndPassword(email, password)
      .then(function(userCredential) {
        // User successfully signed in and is not enrolled with a second factor.
      })
      .catch(function(error) {
        if (error.code == 'auth/multi-factor-auth-required') {
          // The user is a multi-factor user. Second factor challenge is required.
          resolver = error.resolver;
          // ...
        } else if (error.code == 'auth/wrong-password') {
          // Handle other errors such as wrong password.
        } ...
      });
    

    หากปัจจัยแรกของผู้ใช้เป็นผู้ให้บริการแบบรวมศูนย์ เช่น OAuth, SAML หรือ OIDC ให้ตรวจจับข้อผิดพลาดหลังจากเรียกใช้ signInWithPopup() หรือ signInWithRedirect()

  2. หากผู้ใช้ลงทะเบียนปัจจัยรองไว้หลายรายการ ให้ถามผู้ใช้ว่าจะใช้ปัจจัยใด

    Web Modular API

    // Ask user which second factor to use.
    // You can get the masked phone number via resolver.hints[selectedIndex].phoneNumber
    // You can get the display name via resolver.hints[selectedIndex].displayName
    
    if (resolver.hints[selectedIndex].factorId ===
        PhoneMultiFactorGenerator.FACTOR_ID) {
        // User selected a phone second factor.
        // ...
    } else if (resolver.hints[selectedIndex].factorId ===
               TotpMultiFactorGenerator.FACTOR_ID) {
        // User selected a TOTP second factor.
        // ...
    } else {
        // Unsupported second factor.
    }
    

    API ที่ใช้เนมสเปซในเว็บ

    // Ask user which second factor to use.
    // You can get the masked phone number via resolver.hints[selectedIndex].phoneNumber
    // You can get the display name via resolver.hints[selectedIndex].displayName
    if (resolver.hints[selectedIndex].factorId === firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
      // User selected a phone second factor.
      // ...
    } else if (resolver.hints[selectedIndex].factorId === firebase.auth.TotpMultiFactorGenerator.FACTOR_ID) {
      // User selected a TOTP second factor.
      // ...
    } else {
      // Unsupported second factor.
    }
    
  3. เริ่มต้นเครื่องมือยืนยัน reCAPTCHA ตามที่แสดงไว้ในส่วนก่อนหน้า โปรดข้ามขั้นตอนนี้หากมีการกำหนดค่าอินสแตนซ์ reCAPTCHAtchaVerifier แล้ว

    Web Modular API

    import { RecaptchaVerifier } from "firebase/auth";
    
    recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);
    

    API ที่ใช้เนมสเปซในเว็บ

    var recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container-id');
    
  4. เริ่มต้นออบเจ็กต์ PhoneInfoOptions ด้วยหมายเลขโทรศัพท์ของผู้ใช้และเซสชันแบบหลายปัจจัย ค่าเหล่านี้อยู่ในออบเจ็กต์ resolver ที่ส่งผ่านไปยังข้อผิดพลาด auth/multi-factor-auth-required

    Web Modular API

    const phoneInfoOptions = {
        multiFactorHint: resolver.hints[selectedIndex],
        session: resolver.session
    };
    

    API ที่ใช้เนมสเปซในเว็บ

    var phoneInfoOptions = {
      multiFactorHint: resolver.hints[selectedIndex],
      session: resolver.session
    };
    
  5. ส่งข้อความยืนยันไปยังโทรศัพท์ของผู้ใช้:

    Web Modular API

    // Send SMS verification code.
    const phoneAuthProvider = new PhoneAuthProvider(auth);
    phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
        .then(function (verificationId) {
            // verificationId will be needed for sign-in completion.
        });
    

    API ที่ใช้เนมสเปซในเว็บ

    var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
    // Send SMS verification code.
    return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
      .then(function(verificationId) {
        // verificationId will be needed for sign-in completion.
      })
    
  6. หากขอไม่สำเร็จ ให้รีเซ็ต reCAPTCHA แล้วทำขั้นตอนก่อนหน้าซ้ำเพื่อให้ผู้ใช้ลองอีกครั้ง

    Web Modular API

    recaptchaVerifier.clear();
    

    API ที่ใช้เนมสเปซในเว็บ

    recaptchaVerifier.clear();
    
  7. เมื่อส่งรหัส SMS แล้ว ให้ผู้ใช้ยืนยันรหัสโดยทำดังนี้

    Web Modular API

    const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
    

    API ที่ใช้เนมสเปซในเว็บ

    // Ask user for the verification code. Then:
    var cred = firebase.auth.PhoneAuthProvider.credential(verificationId, verificationCode);
    
  8. เริ่มต้นออบเจ็กต์ MultiFactorAssertion ด้วย PhoneAuthCredential ดังนี้

    Web Modular API

    const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
    

    API ที่ใช้เนมสเปซในเว็บ

    var multiFactorAssertion = firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
    
  9. โทรติดต่อ resolver.resolveSignIn() เพื่อตรวจสอบสิทธิ์รองให้เสร็จสมบูรณ์ จากนั้นคุณจะเข้าถึงผลการลงชื่อเข้าใช้เดิมได้ ซึ่งรวมถึงข้อมูลเฉพาะผู้ให้บริการมาตรฐานและข้อมูลเข้าสู่ระบบการตรวจสอบสิทธิ์ ดังนี้

    Web Modular API

    // Complete sign-in. This will also trigger the Auth state listeners.
    resolver.resolveSignIn(multiFactorAssertion)
        .then(function (userCredential) {
            // userCredential will also contain the user, additionalUserInfo, optional
            // credential (null for email/password) associated with the first factor sign-in.
    
            // For example, if the user signed in with Google as a first factor,
            // userCredential.additionalUserInfo will contain data related to Google
            // provider that the user signed in with.
            // - user.credential contains the Google OAuth credential.
            // - user.credential.accessToken contains the Google OAuth access token.
            // - user.credential.idToken contains the Google OAuth ID token.
        });
    

    API ที่ใช้เนมสเปซในเว็บ

    // Complete sign-in. This will also trigger the Auth state listeners.
    resolver.resolveSignIn(multiFactorAssertion)
      .then(function(userCredential) {
        // userCredential will also contain the user, additionalUserInfo, optional
        // credential (null for email/password) associated with the first factor sign-in.
        // For example, if the user signed in with Google as a first factor,
        // userCredential.additionalUserInfo will contain data related to Google provider that
        // the user signed in with.
        // user.credential contains the Google OAuth credential.
        // user.credential.accessToken contains the Google OAuth access token.
        // user.credential.idToken contains the Google OAuth ID token.
      });
    

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

Web Modular API

import {
    getAuth,
    getMultiFactorResolver,
    PhoneAuthProvider,
    PhoneMultiFactorGenerator,
    RecaptchaVerifier,
    signInWithEmailAndPassword
} from "firebase/auth";

const recaptchaVerifier = new RecaptchaVerifier('recaptcha-container-id', undefined, auth);

const auth = getAuth();
signInWithEmailAndPassword(auth, email, password)
    .then(function (userCredential) {
        // User is not enrolled with a second factor and is successfully
        // signed in.
        // ...
    })
    .catch(function (error) {
        if (error.code == 'auth/multi-factor-auth-required') {
            const resolver = getMultiFactorResolver(auth, error);
            // Ask user which second factor to use.
            if (resolver.hints[selectedIndex].factorId ===
                PhoneMultiFactorGenerator.FACTOR_ID) {
                const phoneInfoOptions = {
                    multiFactorHint: resolver.hints[selectedIndex],
                    session: resolver.session
                };
                const phoneAuthProvider = new PhoneAuthProvider(auth);
                // Send SMS verification code
                return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
                    .then(function (verificationId) {
                        // Ask user for the SMS verification code. Then:
                        const cred = PhoneAuthProvider.credential(
                            verificationId, verificationCode);
                        const multiFactorAssertion =
                            PhoneMultiFactorGenerator.assertion(cred);
                        // Complete sign-in.
                        return resolver.resolveSignIn(multiFactorAssertion)
                    })
                    .then(function (userCredential) {
                        // User successfully signed in with the second factor phone number.
                    });
            } else if (resolver.hints[selectedIndex].factorId ===
                       TotpMultiFactorGenerator.FACTOR_ID) {
                // Handle TOTP MFA.
                // ...
            } else {
                // Unsupported second factor.
            }
        } else if (error.code == 'auth/wrong-password') {
            // Handle other errors such as wrong password.
        }
    });

API ที่ใช้เนมสเปซในเว็บ

var resolver;
firebase.auth().signInWithEmailAndPassword(email, password)
  .then(function(userCredential) {
    // User is not enrolled with a second factor and is successfully signed in.
    // ...
  })
  .catch(function(error) {
    if (error.code == 'auth/multi-factor-auth-required') {
      resolver = error.resolver;
      // Ask user which second factor to use.
      if (resolver.hints[selectedIndex].factorId ===
          firebase.auth.PhoneMultiFactorGenerator.FACTOR_ID) {
        var phoneInfoOptions = {
          multiFactorHint: resolver.hints[selectedIndex],
          session: resolver.session
        };
        var phoneAuthProvider = new firebase.auth.PhoneAuthProvider();
        // Send SMS verification code
        return phoneAuthProvider.verifyPhoneNumber(phoneInfoOptions, recaptchaVerifier)
          .then(function(verificationId) {
            // Ask user for the SMS verification code.
            var cred = firebase.auth.PhoneAuthProvider.credential(
                verificationId, verificationCode);
            var multiFactorAssertion =
                firebase.auth.PhoneMultiFactorGenerator.assertion(cred);
            // Complete sign-in.
            return resolver.resolveSignIn(multiFactorAssertion)
          })
          .then(function(userCredential) {
            // User successfully signed in with the second factor phone number.
          });
      } else if (resolver.hints[selectedIndex].factorId ===
        firebase.auth.TotpMultiFactorGenerator.FACTOR_ID) {
        // Handle TOTP MFA.
        // ...
      } else {
        // Unsupported second factor.
      }
    } else if (error.code == 'auth/wrong-password') {
      // Handle other errors such as wrong password.
    } ...
  });

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

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