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

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

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

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

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

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

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

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

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

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

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

    • url: Deep Link ที่จะฝังและสถานะเพิ่มเติมที่จะส่งต่อ โดเมนของลิงก์ต้องอยู่ในรายการที่อนุญาตพิเศษในรายการโดเมนที่ได้รับอนุญาตของคอนโซล Firebase โดยไปที่แท็บวิธีการลงชื่อเข้าใช้ (การตรวจสอบสิทธิ์ -> วิธีการลงชื่อเข้าใช้)
    • 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 พื้นฐาน แล้วจึงลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีดำเนินการนี้ได้ที่ ลิงก์ทั่วไปและโดเมนที่เชื่อมโยงใน 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 Hosting จากขั้นตอนก่อนหน้าลงในความสามารถของโดเมนที่เชื่อมโยง หากใช้โดเมน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 AuthenticationiOS 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;
}

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