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

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

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

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

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

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

  3. ลงทะเบียนแฮช SHA-1 ของแอปในคอนโซล Firebase (การเปลี่ยนแปลงจะนำไปใช้กับ Google Cloud Firebase โดยอัตโนมัติ)

    1. ทำตามขั้นตอนในหัวข้อการตรวจสอบสิทธิ์ไคลเอ็นต์เพื่อรับแฮช SHA-1 ของแอป

    2. เปิดคอนโซล Firebase

    3. ไปที่การตั้งค่าโปรเจ็กต์

    4. คลิกไอคอน Android ในส่วนแอปของคุณ

    5. ทำตามขั้นตอนที่แนะนำเพื่อเพิ่มแฮช SHA-1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Kotlin

    user.multiFactor.session.addOnCompleteListener { task ->     if (task.isSuccessful) {         val multiFactorSession: MultiFactorSession? = task.result     } } 

    Java

    user.getMultiFactor().getSession()   .addOnCompleteListener(       new OnCompleteListener<MultiFactorSession>() {       @Override       public void onComplete(@NonNull Task<MultiFactorSession> task) {         if (task.isSuccessful()) {           MultiFactorSession multiFactorSession = task.getResult();         }       }       }); 
  4. สร้างออบเจ็กต์ OnVerificationStateChangedCallbacks เพื่อจัดการเหตุการณ์ต่างๆ ในกระบวนการยืนยันตัวตน ดังนี้

    Kotlin

    val callbacks = object : OnVerificationStateChangedCallbacks() {     override fun onVerificationCompleted(credential: PhoneAuthCredential) {         // This callback will be invoked in two situations:         // 1) Instant verification. In some cases, the phone number can be         //    instantly verified without needing to send or enter a verification         //    code. You can disable this feature by calling         //    PhoneAuthOptions.builder#requireSmsValidation(true) when building         //    the options to pass to PhoneAuthProvider#verifyPhoneNumber().         // 2) Auto-retrieval. On some devices, Google Play services can         //    automatically detect the incoming verification SMS and perform         //    verification without user action.         this@MainActivity.credential = credential     }      override fun onVerificationFailed(e: FirebaseException) {         // This callback is invoked in response to invalid requests for         // verification, like an incorrect phone number.         if (e is FirebaseAuthInvalidCredentialsException) {             // Invalid request             // ...         } else if (e is FirebaseTooManyRequestsException) {             // The SMS quota for the project has been exceeded             // ...         }         // Show a message and update the UI         // ...     }      override fun onCodeSent(         verificationId: String, forceResendingToken: ForceResendingToken     ) {         // The SMS verification code has been sent to the provided phone number.         // We now need to ask the user to enter the code and then construct a         // credential by combining the code with a verification ID.         // Save the verification ID and resending token for later use.         this@MainActivity.verificationId = verificationId         this@MainActivity.forceResendingToken = forceResendingToken         // ...     } } 

    Java

    OnVerificationStateChangedCallbacks callbacks = new OnVerificationStateChangedCallbacks() {   @Override   public void onVerificationCompleted(PhoneAuthCredential credential) {     // This callback will be invoked in two situations:     // 1) Instant verification. In some cases, the phone number can be     //    instantly verified without needing to send or enter a verification     //    code. You can disable this feature by calling     //    PhoneAuthOptions.builder#requireSmsValidation(true) when building     //    the options to pass to PhoneAuthProvider#verifyPhoneNumber().     // 2) Auto-retrieval. On some devices, Google Play services can     //    automatically detect the incoming verification SMS and perform     //    verification without user action.     this.credential = credential;   }   @Override   public void onVerificationFailed(FirebaseException e) {     // This callback is invoked in response to invalid requests for     // verification, like an incorrect phone number.     if (e instanceof FirebaseAuthInvalidCredentialsException) {     // Invalid request     // ...     } else if (e instanceof FirebaseTooManyRequestsException) {     // The SMS quota for the project has been exceeded     // ...     }     // Show a message and update the UI     // ...   }   @Override   public void onCodeSent(     String verificationId, PhoneAuthProvider.ForceResendingToken token) {     // The SMS verification code has been sent to the provided phone number.     // We now need to ask the user to enter the code and then construct a     // credential by combining the code with a verification ID.     // Save the verification ID and resending token for later use.     this.verificationId = verificationId;     this.forceResendingToken = token;     // ...   } }; 
  5. เริ่มต้นออบเจ็กต์ PhoneInfoOptions ด้วยหมายเลขโทรศัพท์ของผู้ใช้, เซสชันการตรวจสอบสิทธิ์แบบหลายปัจจัย และการเรียกกลับ

    Kotlin

    val phoneAuthOptions = PhoneAuthOptions.newBuilder()     .setPhoneNumber(phoneNumber)     .setTimeout(30L, TimeUnit.SECONDS)     .setMultiFactorSession(MultiFactorSession)     .setCallbacks(callbacks)     .build() 

    Java

    PhoneAuthOptions phoneAuthOptions =   PhoneAuthOptions.newBuilder()       .setPhoneNumber(phoneNumber)       .setTimeout(30L, TimeUnit.SECONDS)       .setMultiFactorSession(multiFactorSession)       .setCallbacks(callbacks)       .build(); 

    ระบบจะเปิดใช้การยืนยันทันทีโดยค่าเริ่มต้น หากต้องการปิดใช้ ให้เพิ่มการเรียกไปที่ requireSmsValidation(true)

  6. ส่งข้อความยืนยันไปยังโทรศัพท์ของผู้ใช้

    Kotlin

    PhoneAuthProvider.verifyPhoneNumber(phoneAuthOptions) 

    Java

    PhoneAuthProvider.verifyPhoneNumber(phoneAuthOptions); 

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

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

    Kotlin

    // Ask user for the verification code. val credential = PhoneAuthProvider.getCredential(verificationId, verificationCode) 

    Java

    // Ask user for the verification code. PhoneAuthCredential credential   = PhoneAuthProvider.getCredential(verificationId, verificationCode); 
  8. เริ่มต้นออบเจ็กต์ MultiFactorAssertion ด้วย PhoneAuthCredential

    Kotlin

    val multiFactorAssertion   = PhoneMultiFactorGenerator.getAssertion(credential) 

    Java

    MultiFactorAssertion multiFactorAssertion   = PhoneMultiFactorGenerator.getAssertion(credential); 
  9. ลงทะเบียนให้เสร็จสมบูรณ์ คุณระบุชื่อที่แสดงสำหรับปัจจัยที่ 2 ได้ด้วย (ไม่บังคับ) ซึ่งมีประโยชน์สําหรับผู้ใช้ที่มีปัจจัยที่ 2 หลายรายการ เนื่องจากระบบจะปกปิดหมายเลขโทรศัพท์ระหว่างขั้นตอนการตรวจสอบสิทธิ์ (เช่น +1******1234)

    Kotlin

    // Complete enrollment. This will update the underlying tokens // and trigger ID token change listener. FirebaseAuth.getInstance()     .currentUser     ?.multiFactor     ?.enroll(multiFactorAssertion, "My personal phone number")     ?.addOnCompleteListener {         // ...     } 

    Java

    // Complete enrollment. This will update the underlying tokens // and trigger ID token change listener. FirebaseAuth.getInstance()   .getCurrentUser()   .getMultiFactor()   .enroll(multiFactorAssertion, "My personal phone number")   .addOnCompleteListener(       new OnCompleteListener<Void>() {       @Override       public void onComplete(@NonNull Task<Void> task) {         // ...       }       }); 

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

Kotlin

val multiFactorAssertion = PhoneMultiFactorGenerator.getAssertion(credential) user.multiFactor.session     .addOnCompleteListener { task ->         if (task.isSuccessful) {             val multiFactorSession = task.result             val phoneAuthOptions = PhoneAuthOptions.newBuilder()                 .setPhoneNumber(phoneNumber)                 .setTimeout(30L, TimeUnit.SECONDS)                 .setMultiFactorSession(multiFactorSession)                 .setCallbacks(callbacks)                 .build()             // Send SMS verification code.             PhoneAuthProvider.verifyPhoneNumber(phoneAuthOptions)         }     }  // Ask user for the verification code. val credential = PhoneAuthProvider.getCredential(verificationId, verificationCode)  val multiFactorAssertion = PhoneMultiFactorGenerator.getAssertion(credential)  // Complete enrollment. FirebaseAuth.getInstance()     .currentUser     ?.multiFactor     ?.enroll(multiFactorAssertion, "My personal phone number")     ?.addOnCompleteListener {         // ...     } 

Java

MultiFactorAssertion multiFactorAssertion = PhoneMultiFactorGenerator.getAssertion(credential); user.getMultiFactor().getSession()   .addOnCompleteListener(       new OnCompleteListener<MultiFactorSession>() {       @Override       public void onComplete(@NonNull Task<MultiFactorSession> task) {         if (task.isSuccessful()) {           MultiFactorSession multiFactorSession = task.getResult();           PhoneAuthOptions phoneAuthOptions =             PhoneAuthOptions.newBuilder()                 .setPhoneNumber(phoneNumber)                 .setTimeout(30L, TimeUnit.SECONDS)                 .setMultiFactorSession(multiFactorSession)                 .setCallbacks(callbacks)                 .build();           // Send SMS verification code.           PhoneAuthProvider.verifyPhoneNumber(phoneAuthOptions);         }       }       });  // Ask user for the verification code. PhoneAuthCredential credential =   PhoneAuthProvider.getCredential(verificationId, verificationCode);  MultiFactorAssertion multiFactorAssertion = PhoneMultiFactorGenerator.getAssertion(credential); // Complete enrollment. FirebaseAuth.getInstance()   .getCurrentUser()   .getMultiFactor()   .enroll(multiFactorAssertion, "My personal phone number")   .addOnCompleteListener(       new OnCompleteListener<Void>() {       @Override       public void onComplete(@NonNull Task<Void> task) {         // ...       }       }); 

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

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

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

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

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

    Kotlin

    FirebaseAuth.getInstance()     .signInWithEmailAndPassword(email, password)     .addOnCompleteListener(         OnCompleteListener { task ->             if (task.isSuccessful) {                 // User is not enrolled with a second factor and is successfully                 // signed in.                 // ...                 return@OnCompleteListener             }             if (task.exception is FirebaseAuthMultiFactorException) {                 // The user is a multi-factor user. Second factor challenge is                 // required.                 val multiFactorResolver =                     (task.exception as FirebaseAuthMultiFactorException).resolver                 // ...             } else {                 // Handle other errors, such as wrong password.             }         }) 

    Java

    FirebaseAuth.getInstance()   .signInWithEmailAndPassword(email, password)   .addOnCompleteListener(       new OnCompleteListener<AuthResult>() {       @Override       public void onComplete(@NonNull Task<AuthResult> task) {         if (task.isSuccessful()) {           // User is not enrolled with a second factor and is successfully           // signed in.           // ...           return;         }         if (task.getException() instanceof FirebaseAuthMultiFactorException) {           // The user is a multi-factor user. Second factor challenge is           // required.           MultiFactorResolver multiFactorResolver = task.getException().getResolver();           // ...         } else {           // Handle other errors such as wrong password.         }       }       }); 

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

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

    Kotlin

    // Ask user which second factor to use. // You can get the list of enrolled second factors using //   multiFactorResolver.hints  // Check the selected factor: if (multiFactorResolver.hints[selectedIndex].factorId     === PhoneMultiFactorGenerator.FACTOR_ID ) {     // User selected a phone second factor.     val selectedHint =         multiFactorResolver.hints[selectedIndex] as PhoneMultiFactorInfo } else if (multiFactorResolver.hints[selectedIndex].factorId     === TotpMultiFactorGenerator.FACTOR_ID) {     // User selected a TOTP second factor. } else {     // Unsupported second factor. } 

    Java

    // Ask user which second factor to use. // You can get the masked phone number using // resolver.getHints().get(selectedIndex).getPhoneNumber() // You can get the display name using // resolver.getHints().get(selectedIndex).getDisplayName() if ( resolver.getHints()                .get(selectedIndex)                .getFactorId()                .equals( PhoneMultiFactorGenerator.FACTOR_ID ) ) { // User selected a phone second factor. MultiFactorInfo selectedHint =   multiFactorResolver.getHints().get(selectedIndex); } else if ( resolver               .getHints()               .get(selectedIndex)               .getFactorId()               .equals(TotpMultiFactorGenerator.FACTOR_ID ) ) {   // User selected a TOTP second factor. } else { // Unsupported second factor. } 
  3. เริ่มต้นออบเจ็กต์ PhoneAuthOptions ด้วยคำแนะนำและเซสชันการตรวจสอบสิทธิ์แบบหลายปัจจัย ค่าเหล่านี้อยู่ในโปรแกรมแก้ไขที่แนบมากับ FirebaseAuthMultiFactorException

    Kotlin

    val phoneAuthOptions = PhoneAuthOptions.newBuilder()     .setMultiFactorHint(selectedHint)     .setTimeout(30L, TimeUnit.SECONDS)     .setMultiFactorSession(multiFactorResolver.session)     .setCallbacks(callbacks) // Optionally disable instant verification.     // .requireSmsValidation(true)     .build() 

    Java

    PhoneAuthOptions phoneAuthOptions =   PhoneAuthOptions.newBuilder()       .setMultiFactorHint(selectedHint)       .setTimeout(30L, TimeUnit.SECONDS)       .setMultiFactorSession(multiFactorResolver.getSession())       .setCallbacks(callbacks)       // Optionally disable instant verification.       // .requireSmsValidation(true)       .build(); 
  4. ส่งข้อความยืนยันไปยังโทรศัพท์ของผู้ใช้

    Kotlin

    // Send SMS verification code PhoneAuthProvider.verifyPhoneNumber(phoneAuthOptions) 

    Java

    // Send SMS verification code PhoneAuthProvider.verifyPhoneNumber(phoneAuthOptions); 
  5. เมื่อส่งรหัส SMS แล้ว ให้ขอให้ผู้ใช้ยืนยันรหัสโดยทำดังนี้

    Kotlin

    // Ask user for the verification code. Then, pass it to getCredential: val credential =     PhoneAuthProvider.getCredential(verificationId, verificationCode) 

    Java

    // Ask user for the verification code. Then, pass it to getCredential: PhoneAuthCredential credential     = PhoneAuthProvider.getCredential(verificationId, verificationCode); 
  6. เริ่มต้นออบเจ็กต์ MultiFactorAssertion ด้วย PhoneAuthCredential

    Kotlin

    val multiFactorAssertion = PhoneMultiFactorGenerator.getAssertion(credential) 

    Java

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

    Kotlin

    multiFactorResolver     .resolveSignIn(multiFactorAssertion)     .addOnCompleteListener { task ->         if (task.isSuccessful) {             val authResult = task.result             // AuthResult will also contain the user, additionalUserInfo,             // and an 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, authResult.getAdditionalUserInfo() will contain data             // related to Google provider that the user signed in with;             // authResult.getCredential() will contain the Google OAuth             //   credential;             // authResult.getCredential().getAccessToken() will contain the             //   Google OAuth access token;             // authResult.getCredential().getIdToken() contains the Google             //   OAuth ID token.         }     } 

    Java

    multiFactorResolver   .resolveSignIn(multiFactorAssertion)   .addOnCompleteListener(       new OnCompleteListener<AuthResult>() {       @Override       public void onComplete(@NonNull Task<AuthResult> task) {         if (task.isSuccessful()) {           AuthResult authResult = task.getResult();           // AuthResult will also contain the user, additionalUserInfo,           // and an 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, authResult.getAdditionalUserInfo() will contain data           // related to Google provider that the user signed in with.           // authResult.getCredential() will contain the Google OAuth           // credential.           // authResult.getCredential().getAccessToken() will contain the           // Google OAuth access token.           // authResult.getCredential().getIdToken() contains the Google           // OAuth ID token.         }       }       }); 

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

Kotlin

FirebaseAuth.getInstance()     .signInWithEmailAndPassword(email, password)     .addOnCompleteListener { task ->         if (task.isSuccessful) {             // User is not enrolled with a second factor and is successfully             // signed in.             // ...             return@addOnCompleteListener         }         if (task.exception is FirebaseAuthMultiFactorException) {             val multiFactorResolver =                 (task.exception as FirebaseAuthMultiFactorException).resolver              // Ask user which second factor to use. Then, get             // the selected hint:             val selectedHint =                 multiFactorResolver.hints[selectedIndex] as PhoneMultiFactorInfo              // Send the SMS verification code.             PhoneAuthProvider.verifyPhoneNumber(                 PhoneAuthOptions.newBuilder()                     .setActivity(this)                     .setMultiFactorSession(multiFactorResolver.session)                     .setMultiFactorHint(selectedHint)                     .setCallbacks(generateCallbacks())                     .setTimeout(30L, TimeUnit.SECONDS)                     .build()             )              // Ask user for the SMS verification code, then use it to get             // a PhoneAuthCredential:             val credential =                 PhoneAuthProvider.getCredential(verificationId, verificationCode)              // Initialize a MultiFactorAssertion object with the             // PhoneAuthCredential.             val multiFactorAssertion: MultiFactorAssertion =                 PhoneMultiFactorGenerator.getAssertion(credential)              // Complete sign-in.             multiFactorResolver                 .resolveSignIn(multiFactorAssertion)                 .addOnCompleteListener { task ->                     if (task.isSuccessful) {                         // User successfully signed in with the                         // second factor phone number.                     }                     // ...                 }         } else {             // Handle other errors such as wrong password.         }     } 

Java

FirebaseAuth.getInstance()   .signInWithEmailAndPassword(email, password)   .addOnCompleteListener(       new OnCompleteListener<AuthResult>() {       @Override       public void onComplete(@NonNull Task<AuthResult> task) {         if (task.isSuccessful()) {           // User is not enrolled with a second factor and is successfully           // signed in.           // ...           return;         }         if (task.getException() instanceof FirebaseAuthMultiFactorException) {           FirebaseAuthMultiFactorException e =             (FirebaseAuthMultiFactorException) task.getException();            MultiFactorResolver multiFactorResolver = e.getResolver();            // Ask user which second factor to use.           MultiFactorInfo selectedHint =             multiFactorResolver.getHints().get(selectedIndex);            // Send the SMS verification code.           PhoneAuthProvider.verifyPhoneNumber(             PhoneAuthOptions.newBuilder()                 .setActivity(this)                 .setMultiFactorSession(multiFactorResolver.getSession())                 .setMultiFactorHint(selectedHint)                 .setCallbacks(generateCallbacks())                 .setTimeout(30L, TimeUnit.SECONDS)                 .build());            // Ask user for the SMS verification code.           PhoneAuthCredential credential =             PhoneAuthProvider.getCredential(verificationId, verificationCode);            // Initialize a MultiFactorAssertion object with the           // PhoneAuthCredential.           MultiFactorAssertion multiFactorAssertion =             PhoneMultiFactorGenerator.getAssertion(credential);            // Complete sign-in.           multiFactorResolver             .resolveSignIn(multiFactorAssertion)             .addOnCompleteListener(                 new OnCompleteListener<AuthResult>() {                   @Override                   public void onComplete(@NonNull Task<AuthResult> task) {                   if (task.isSuccessful()) {                     // User successfully signed in with the                     // second factor phone number.                   }                   // ...                   }                 });         } else {           // Handle other errors such as wrong password.         }       }       }); 

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

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