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

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

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

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

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

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

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

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

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

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

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

    • url: Deep Link ที่จะฝังและสถานะเพิ่มเติมที่จะส่งต่อ โดเมนของลิงก์ต้องอยู่ในรายการโดเมนที่ได้รับอนุญาตของคอนโซล Firebase ซึ่งดูได้โดยไปที่แท็บวิธีการลงชื่อเข้าใช้ (การตรวจสอบสิทธิ์ -> วิธีการลงชื่อเข้าใช้)
    • iOSBundleID และ androidPackageName: ช่วย Firebase Authentication ในการพิจารณาว่าจะสร้างลิงก์สำหรับเว็บเท่านั้นหรือลิงก์สำหรับมือถือซึ่งจะเปิดในอุปกรณ์ Android หรือ Apple
    • handleCodeInApp: ตั้งค่าเป็น "จริง" การดำเนินการลงชื่อเข้าใช้ต้องดำเนินการให้เสร็จสมบูรณ์ในแอปเสมอ ซึ่งแตกต่างจากการดำเนินการทางอีเมลอื่นๆ นอกแอป (การรีเซ็ตรหัสผ่านและการยืนยันอีเมล) เนื่องจากในตอนท้ายของขั้นตอน ผู้ใช้จะต้องลงชื่อเข้าใช้และระบบจะเก็บสถานะการตรวจสอบสิทธิ์ไว้ในแอป
    • linkDomain: เมื่อมีการกำหนดโดเมนลิงก์ที่กำหนดเองสำหรับโปรเจ็กต์ ให้ระบุโดเมนที่จะใช้เมื่อแอปบนอุปกรณ์เคลื่อนที่ที่ระบุจะเปิดลิงก์ มิเช่นนั้นระบบจะเลือกโดเมนเริ่มต้นโดยอัตโนมัติ (เช่น PROJECT_ID.firebaseapp.com)Hosting
    • 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 กำหนดให้ระบุอีเมลของผู้ใช้เมื่อดำเนินการตามขั้นตอนการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ อีเมลนี้ต้องตรงกับอีเมลที่ส่งลิงก์การลงชื่อเข้าใช้ไปให้ในตอนแรกเพื่อให้การลงชื่อเข้าใช้สำเร็จ

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

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

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

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

กำหนดค่า Firebase Hosting

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

  1. กำหนดค่าโดเมน Firebase Hosting โดยทำดังนี้

    ในคอนโซล Firebase ให้เปิดส่วน Hosting

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

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

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

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

    คุณจะต้องกำหนดค่าโดเมนที่เลือกเป็นโดเมนที่เชื่อมโยง สำหรับ App Link หากต้องการตั้งค่าการให้สิทธิ์ในแอป ให้เปิดแท็บ Signing & Capabilities ของเป้าหมายใน 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.
  }];

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

ก่อน 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;
}

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