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

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

Firebase Authentication with Identity Platform ช่วยให้คุณใช้ TOTP เป็นปัจจัยเพิ่มเติมสำหรับ MFA ได้ เมื่อคุณเปิดใช้ฟีเจอร์นี้ ผู้ใช้ที่พยายามลงชื่อเข้าใช้แอปจะเห็นคําขอ TOTP ในการสร้างรหัส บุคคลต้องใช้แอป Authenticator ที่สร้างรหัส TOTP ที่ถูกต้องได้ เช่น Google Authenticator

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

  1. เปิดใช้ผู้ให้บริการที่รองรับ MFA อย่างน้อย 1 ราย โปรดทราบว่าผู้ให้บริการทั้งหมดยกเว้นการรองรับ MFA ต่อไปนี้

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

  3. ติดตั้ง Firebase Apple SDK หากยังไม่ได้ทำ

    TOTP MFA ได้รับการสนับสนุนเฉพาะใน Apple SDK เวอร์ชัน 10.12.0 ขึ้นไป และบน iOS เท่านั้น

เปิดใช้ MFA ของ TOTP

หากต้องการเปิดใช้ TOTP เป็นปัจจัยที่ 2 ให้ใช้ Admin SDK หรือเรียกใช้ปลายทาง REST สำหรับการกําหนดค่าโปรเจ็กต์

หากต้องการใช้ Admin SDK ให้ทําดังนี้

  1. ติดตั้ง Firebase Admin Node.js SDK หากยังไม่ได้ดำเนินการ

    ฟีเจอร์นี้ใช้ได้กับ Firebase Admin Node.js SDK เวอร์ชัน 11.6.0 ขึ้นไปเท่านั้น

  2. เรียกใช้คำสั่งต่อไปนี้

    import { getAuth } from 'firebase-admin/auth';
    
    getAuth().projectConfigManager().updateProjectConfig(
    {
          multiFactorConfig: {
              providerConfigs: [{
                  state: "ENABLED",
                  totpProviderConfig: {
                      adjacentIntervals: NUM_ADJ_INTERVALS
                  }
              }]
          }
    })
    

    แทนที่ค่าต่อไปนี้

    • NUM_ADJ_INTERVALS: จำนวนช่วงเวลาถัดไปติดกันที่จะยอมรับ TOTP ตั้งแต่ 0 ถึง 10 ค่าเริ่มต้นคือ 5

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

หากต้องการเปิดใช้ MFA โดยใช้ TOTP โดยใช้ REST API ให้เรียกใช้คำสั่งต่อไปนี้

curl -X PATCH "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=mfa" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: PROJECT_ID" \
    -d \
    '{
        "mfa": {
          "providerConfigs": [{
            "state": "ENABLED",
            "totpProviderConfig": {
              "adjacentIntervals": NUM_ADJ_INTERVALS
            }
          }]
       }
    }'

แทนที่ข้อมูลต่อไปนี้

  • PROJECT_ID: รหัสโปรเจ็กต์
  • NUM_ADJ_INTERVALS: จํานวนช่วงเวลาของกรอบเวลาตั้งแต่ 0 ถึง 10 ค่าเริ่มต้นคือ 5

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

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

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

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

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

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

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

ลงทะเบียนผู้ใช้ใน MFA ของ TOTP

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

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

  2. สร้างข้อมูลลับ TOTP สำหรับผู้ใช้ที่ตรวจสอบสิทธิ์แล้ว โดยทำดังนี้

    // Generate a TOTP secret.
    guard let mfaSession = try? await currentUser.multiFactor.session() else { return }
    guard let totpSecret = try? await TOTPMultiFactorGenerator.generateSecret(with: mfaSession) else { return }
    
    // Display the secret to the user and prompt them to enter it into their
    // authenticator app. (See the next step.)
    
  3. แสดงรหัสลับให้ผู้ใช้เห็นและแจ้งให้ผู้ใช้ป้อนรหัสลับลงในแอปตรวจสอบสิทธิ์

    // Display this key:
    let secret = totpSecret.sharedSecretKey()
    

    นอกจากการแสดงคีย์ลับแล้ว คุณยังพยายามเพิ่มคีย์ดังกล่าวลงในแอปตรวจสอบสิทธิ์เริ่มต้นของอุปกรณ์โดยอัตโนมัติได้ด้วย โดยสร้าง URI ของคีย์ที่เข้ากันได้กับ Google Authenticator แล้วส่งไปยัง openInOTPApp(withQRCodeURL:) ดังนี้

    let otpAuthUri = totpSecret.generateQRCodeURL(
        withAccountName: currentUser.email ?? "default account",
        issuer: "Your App Name")
    totpSecret.openInOTPApp(withQRCodeURL: otpAuthUri)
    

    หลังจากผู้ใช้เพิ่มข้อมูลลับลงในแอปตรวจสอบสิทธิ์แล้ว แอปจะเริ่มสร้าง TOTP

  4. แจ้งให้ผู้ใช้พิมพ์ TOTP ที่แสดงโดยแอป Authenticator และใช้ TOTP ดังกล่าวเพื่อลงทะเบียน MFA ให้เสร็จสมบูรณ์

    // Ask the user for a verification code from the authenticator app.
    let verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    let multiFactorAssertion = TOTPMultiFactorGenerator.assertionForEnrollment(
        with: totpSecret,
        oneTimePassword: verificationCode)
    do {
        try await currentUser.multiFactor.enroll(
            with: multiFactorAssertion,
            displayName: "TOTP")
    } catch {
        // Wrong or expired OTP. Re-prompt the user.
    }
    

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

หากต้องการลงชื่อเข้าใช้ผู้ใช้ด้วย MFA แบบ TOTP ให้ใช้รหัสต่อไปนี้

  1. เรียกใช้เมธอด signIn(with...:) อย่างใดอย่างหนึ่งตามปกติหากคุณไม่ได้ใช้ MFA (เช่น signIn(withEmail:password:)) หากเมธอดแสดงข้อผิดพลาดที่มีรหัส secondFactorRequired ให้เริ่มขั้นตอนการยืนยันแบบหลายปัจจัยของแอป

    do {
        let authResult = try await Auth.auth().signIn(withEmail: email, password: password)
    
        // If the user is not enrolled with a second factor and provided valid
        // credentials, sign-in succeeds.
    
        // (If your app requires MFA, this could be considered an error
        // condition, which you would resolve by forcing the user to enroll a
        // second factor.)
    
        // ...
    } catch let error as AuthErrorCode where error.code == .secondFactorRequired {
        // Initiate your second factor sign-in flow. (See next step.)
        // ...
    } catch {
        // Other auth error.
        throw error
    }
    
  2. ขั้นตอน MFA ของแอปควรแจ้งให้ผู้ใช้เลือกปัจจัยที่ 2 ที่ต้องการใช้ก่อน คุณดูรายการปัจจัยที่ 2 ที่รองรับได้โดยตรวจสอบพร็อพเพอร์ตี้ hints ของอินสแตนซ์ MultiFactorResolver

    let mfaKey = AuthErrorUserInfoMultiFactorResolverKey
    guard let resolver = error.userInfo[mfaKey] as? MultiFactorResolver else { return }
    let enrolledFactors = resolver.hints.map(\.displayName)
    
  3. หากผู้ใช้เลือกที่จะใช้ TOTP ให้แจ้งให้ผู้ใช้พิมพ์ TOTP ที่แสดงในแอป Authenticator และใช้ TOTP ดังกล่าวเพื่อลงชื่อเข้าใช้

    let multiFactorInfo = resolver.hints[selectedIndex]
    switch multiFactorInfo.factorID {
    case TOTPMultiFactorID:
        let otpFromAuthenticator = // OTP typed by the user.
        let assertion = TOTPMultiFactorGenerator.assertionForSignIn(
            withEnrollmentID: multiFactorInfo.uid,
            oneTimePassword: otpFromAuthenticator)
        do {
            let authResult = try await resolver.resolveSignIn(with: assertion)
        } catch {
            // Wrong or expired OTP. Re-prompt the user.
        }
    default:
        return
    }
    

ยกเลิกการลงทะเบียน MFA โดยใช้ TOTP

ส่วนนี้จะอธิบายวิธีจัดการเมื่อผู้ใช้ยกเลิกการลงทะเบียนจาก MFA ของ TOTP

หากผู้ใช้ลงชื่อสมัครใช้ตัวเลือก MFA หลายรายการ และยกเลิกการลงทะเบียนจากตัวเลือกที่เปิดใช้ล่าสุด ผู้ใช้จะได้รับ auth/user-token-expired และระบบจะออกจากระบบ ผู้ใช้ต้องลงชื่อเข้าใช้อีกครั้งและยืนยันข้อมูลเข้าสู่ระบบที่มีอยู่ เช่น อีเมลและรหัสผ่าน

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

guard let currentUser = Auth.auth().currentUser else { return }

// Prompt the user to select a factor to unenroll, from this array:
currentUser.multiFactor.enrolledFactors

// ...

// Unenroll the second factor.
let multiFactorInfo = currentUser.multiFactor.enrolledFactors[selectedIndex]
do {
    try await currentUser.multiFactor.unenroll(with: multiFactorInfo)
} catch let error as AuthErrorCode where error.code == .invalidUserToken {
    // Second factor unenrolled, but the user was signed out. Re-authenticate
    // them.
}

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