ตรวจสอบสิทธิ์ด้วย Firebase โดยใช้ลิงก์อีเมลบนแพลตฟอร์ม Apple

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

การลงชื่อเข้าใช้ด้วยอีเมลมีสิทธิประโยชน์มากมาย ดังนี้

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

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

ใช้ Swift Package Manager เพื่อติดตั้งและจัดการทรัพยากร Dependency ของ Firebase

  1. ใน Xcode ขณะที่โปรเจ็กต์แอปเปิดอยู่ ให้ไปที่ไฟล์ > เพิ่มแพ็กเกจ
  2. เมื่อได้รับข้อความแจ้ง ให้เพิ่มที่เก็บ SDK ของแพลตฟอร์ม Apple ของ Firebase โดยทำดังนี้
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. เลือกFirebase Authenticationคลัง
  5. เพิ่มแฟล็ก -ObjC ลงในส่วนแฟล็ก Linker อื่นๆ ของการตั้งค่าบิลด์ของเป้าหมาย
  6. เมื่อเสร็จแล้ว Xcode จะเริ่มแก้ไขและดาวน์โหลดการขึ้นต่อกันในเบื้องหลังโดยอัตโนมัติ

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

  1. ในคอนโซล Firebase ให้ไปที่ความปลอดภัย > การตรวจสอบสิทธิ์

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

  3. ในส่วนเดียวกัน ให้เปิดใช้ผู้ให้บริการลิงก์อีเมล (การลงชื่อเข้าใช้แบบไม่ต้องใช้รหัสผ่าน)

  4. คลิกบันทึก

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

  1. สร้างออบเจ็กต์ ActionCodeSettings ซึ่งจะให้คำสั่งแก่ Firebase เกี่ยวกับวิธีสร้างลิงก์อีเมล ตั้งค่าช่องต่อไปนี้

    • url: Deep Link ที่จะฝังและสถานะเพิ่มเติมที่จะส่งต่อ หากยังไม่ได้เพิ่ม ให้เพิ่มโดเมนลงในรายการโดเมนที่ได้รับอนุญาตโดยทำดังนี้

      1. ในFirebaseคอนโซล ให้ไปที่ ความปลอดภัย > การตรวจสอบสิทธิ์ > แท็บการตั้งค่า

      2. ในส่วนโดเมนที่ได้รับอนุญาต ให้คลิกเพิ่มโดเมน แล้วเพิ่มโดเมน

    • iOSBundleID และ androidPackageName: ช่วย Firebase Authentication ระบุ ว่าควรสร้างลิงก์สำหรับเว็บเท่านั้นหรือลิงก์สำหรับมือถือซึ่งเปิดในอุปกรณ์ Android หรือ Apple
    • handleCodeInApp: ตั้งค่าเป็น "จริง" การดำเนินการลงชื่อเข้าใช้ต้องดำเนินการในแอปเสมอ ซึ่งแตกต่างจากการดำเนินการทางอีเมลอื่นๆ นอกแบนด์ (การรีเซ็ตรหัสผ่านและการยืนยันอีเมล) เนื่องจากในตอนท้ายของโฟลว์ ระบบคาดหวังให้ผู้ใช้ลงชื่อเข้าใช้และเก็บสถานะการให้สิทธิ์ไว้ภายใน แอป
    • linkDomain: เมื่อกำหนดHostingโดเมนลิงก์ที่กำหนดเองสำหรับโปรเจ็กต์ ให้ระบุโดเมนที่จะใช้เมื่อแอปบนอุปกรณ์เคลื่อนที่ที่ระบุเปิดลิงก์ มิฉะนั้นระบบจะเลือกโดเมนเริ่มต้นโดยอัตโนมัติ (เช่น PROJECT_ID.firebaseapp.com)
    • dynamicLinkDomain: เลิกใช้งานแล้ว ไม่ต้องระบุพารามิเตอร์นี้

    Swift

    let actionCodeSettings = ActionCodeSettings()
    actionCodeSettings.url = URL(string: "https://www.example.com")
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = true
    actionCodeSettings.setIOSBundleID(Bundle.main.bundleIdentifier!)
    actionCodeSettings.setAndroidPackageName("com.example.android",
                                             installIfNotAvailable: false, minimumVersion: "12")

    Objective-C

    FIRActionCodeSettings *actionCodeSettings = [[FIRActionCodeSettings alloc] init];
    [actionCodeSettings setURL:[NSURL URLWithString:@"https://www.example.com"]];
    // The sign-in operation has to always be completed in the app.
    actionCodeSettings.handleCodeInApp = YES;
    [actionCodeSettings setIOSBundleID:[[NSBundle mainBundle] bundleIdentifier]];
    [actionCodeSettings setAndroidPackageName:@"com.example.android"
                        installIfNotAvailable:NO
                               minimumVersion:@"12"];

    ดูข้อมูลเพิ่มเติมเกี่ยวกับ ActionCodeSettings ได้ที่ส่วน การส่งสถานะในการดำเนินการทางอีเมล

  2. ขออีเมลจากผู้ใช้

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

    Swift

    Auth.auth().sendSignInLink(toEmail: email,
                               actionCodeSettings: actionCodeSettings) { error in
      // ...
        if let error = error {
          self.showMessagePrompt(error.localizedDescription)
          return
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        UserDefaults.standard.set(email, forKey: "Email")
        self.showMessagePrompt("Check your email for link")
        // ...
    }

    Objective-C

    [[FIRAuth auth] sendSignInLinkToEmail:email
                       actionCodeSettings:actionCodeSettings
                               completion:^(NSError *_Nullable error) {
      // ...
        if (error) {
          [self showMessagePrompt:error.localizedDescription];
           return;
        }
        // The link was successfully sent. Inform the user.
        // Save the email locally so you don't need to ask the user for it again
        // if they open the link on the same device.
        [NSUserDefaults.standardUserDefaults setObject:email forKey:@"Email"];
        [self showMessagePrompt:@"Check your email for link"];
        // ...
    }];

ข้อกังวลด้านความปลอดภัย

Firebase Auth กำหนดให้ต้องระบุอีเมลของผู้ใช้เมื่อทำขั้นตอนการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ เพื่อป้องกันไม่ให้มีการใช้ลิงก์การลงชื่อเข้าใช้เพื่อลงชื่อเข้าใช้ในฐานะผู้ใช้ที่ไม่ต้องการหรือในอุปกรณ์ที่ไม่ต้องการ อีเมลนี้ต้องตรงกับอีเมลที่ระบบส่งลิงก์ลงชื่อเข้าใช้ไปให้ในตอนแรกเพื่อให้ลงชื่อเข้าใช้ได้

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

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

การลงชื่อเข้าใช้ในแอปบนอุปกรณ์เคลื่อนที่ของ Apple ให้เสร็จสมบูรณ์

Firebase Authentication ใช้ Firebase Hosting เพื่อส่งลิงก์อีเมลไปยังอุปกรณ์เคลื่อนที่ หากต้องการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ด้วยแอปพลิเคชันบนอุปกรณ์เคลื่อนที่ คุณต้องกำหนดค่าแอปพลิเคชันให้ตรวจหาลิงก์แอปพลิเคชันขาเข้า แยกวิเคราะห์ Deep Link พื้นฐาน แล้วจึงลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีดำเนินการนี้ได้ที่ ใน Universal Link และโดเมนที่เชื่อมโยงใน iOS

กำหนดค่า Firebase Hosting

Firebase Authentication ใช้โดเมน Firebase Hosting เมื่อ สร้างและส่งลิงก์ที่มีไว้เพื่อเปิดในแอปพลิเคชันบนอุปกรณ์เคลื่อนที่ ระบบได้กำหนดค่าFirebase Hostingโดเมนเริ่มต้นให้คุณแล้ว

  1. กำหนดค่าโดเมน Firebase Hosting

    ในFirebaseคอนโซล ให้ไปที่โฮสติ้งและแบบไม่มีเซิร์ฟเวอร์ > โฮสติ้ง

    • หากต้องการใช้โดเมนเริ่มต้นสำหรับลิงก์อีเมลที่เปิดในแอปพลิเคชันบนอุปกรณ์เคลื่อนที่ ให้ไปที่เว็บไซต์เริ่มต้นและจดบันทึกโดเมน Hosting เริ่มต้น โดยปกติแล้ว โดเมน Hosting เริ่มต้นจะมีลักษณะดังนี้ PROJECT_ID.firebaseapp.com

      คุณจะต้องใช้ค่านี้เมื่อกำหนดค่าแอปเพื่อสกัดกั้นลิงก์ขาเข้า

    • หากต้องการใช้โดเมนที่กำหนดเองสำหรับลิงก์อีเมล คุณสามารถ ลงทะเบียนโดเมนกับ Firebase Hosting และใช้โดเมนดังกล่าวสำหรับโดเมนของลิงก์

  2. การกำหนดค่าแอปพลิเคชันของ Apple

    คุณจะต้องกำหนดค่าโดเมนที่เลือกเป็นโดเมนที่เชื่อมโยงสำหรับ App Link หากต้องการตั้งค่าการให้สิทธิ์ในแอป ให้เปิดแท็บการลงนามและความสามารถของเป้าหมายใน Xcode แล้วเพิ่มโดเมนโฮสติ้งของ Firebase จากขั้นตอนก่อนหน้าลงในความสามารถของโดเมนที่เชื่อมโยง หากใช้โดเมน Firebase Hosting เริ่มต้น ค่านี้จะเป็น applinks:PROJECT_ID.firebaseapp.com

    ดูข้อมูลเพิ่มเติมได้ที่การรองรับโดเมนที่เชื่อมโยง ในเว็บไซต์เอกสารประกอบของ Apple

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

Swift

if Auth.auth().isSignIn(withEmailLink: link) {
        Auth.auth().signIn(withEmail: email, link: self.link) { user, error in
          // ...
        }
}

Objective-C

if ([[FIRAuth auth] isSignInWithEmailLink:link]) {
    [[FIRAuth auth] signInWithEmail:email
                               link:link
                         completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      // ...
    }];
}

ดูวิธีจัดการการลงชื่อเข้าใช้ด้วยลิงก์อีเมลในแอปพลิเคชัน Android ได้ที่คู่มือ Android

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

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

ความแตกต่างจะอยู่ในครึ่งหลังของการดำเนินการ

Swift

  let credential = EmailAuthCredential.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.link(with: credential) { authData, error in
    if (error) {
      // And error occurred during linking.
      return
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthProvider credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      linkWithCredential:credential
              completion:^(FIRAuthDataResult *_Nullable result,
                           NSError *_Nullable error) {
    if (error) {
      // And error occurred during linking.
      return;
    }
    // The provider was successfully linked.
    // The phone user can now sign in with their phone number or email.
  }];

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

Swift

  let credential = EmailAuthProvider.credential(withEmail:email
                                                       link:link)
  Auth.auth().currentUser?.reauthenticate(with: credential) { authData, error in
    if (error) {
      // And error occurred during re-authentication.
      return
    }
    // The user was successfully re-authenticated.
  }

Objective-C

  FIRAuthCredential *credential =
      [FIREmailAuthCredential credentialWithEmail:email link:link];
  [FIRAuth auth].currentUser
      reauthenticateWithCredential:credential
                        completion:^(FIRAuthDataResult *_Nullable result,
                                     NSError *_Nullable error) {
    if (error) {
      // And error occurred during re-authentication
      return;
    }
    // The user was successfully re-authenticated.
  }];

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

ก่อน Firebase Authentication iOS SDK v11.8.0 ฟีเจอร์การลงชื่อเข้าใช้ด้วยลิงก์อีเมล อาศัย Firebase Dynamic Links ในการเปิดลิงก์ลงชื่อเข้าใช้ในแอปที่ถูกต้อง ลิงก์ยืนยันเหล่านี้จะเลิกใช้งาน เนื่องจาก Firebase Dynamic Links จะปิดตัวในวันที่ 25 สิงหาคม 2025

หากแอปใช้ลิงก์รูปแบบเก่า คุณควรย้ายข้อมูลแอปไปยังระบบใหม่ที่อิงตาม Firebase Hosting

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

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

ดูข้อมูลเพิ่มเติมได้ที่เปิดหรือปิดใช้การป้องกันการแจงนับอีเมล

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

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

  • ในแอป คุณสามารถรับข้อมูลโปรไฟล์พื้นฐานของผู้ใช้จากออบเจ็กต์ User ดูจัดการผู้ใช้

  • ใน Firebase Realtime Database และ Cloud Storage กฎความปลอดภัย คุณสามารถ รับรหัสผู้ใช้ที่ไม่ซ้ำของผู้ใช้ที่ลงชื่อเข้าใช้จากตัวแปร auth และใช้รหัสดังกล่าวเพื่อควบคุมข้อมูลที่ผู้ใช้เข้าถึงได้

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

หากต้องการนำผู้ใช้ออกจากระบบ ให้เรียกใช้ signOut:

Swift

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

Objective-C

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

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