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

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

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

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

ก่อนจะเริ่ม

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

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

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

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

เพื่อเริ่มต้นการไหลของการตรวจสอบนำเสนอผู้ใช้ที่มีอินเตอร์เฟซที่จะแจ้งให้ผู้ใช้เพื่อให้ที่อยู่อีเมลของพวกเขาแล้วโทร sendSignInLinkToEmail:actionCodeSettings:completion: ขอให้ส่ง Firebase การเชื่อมโยงการตรวจสอบไปยังอีเมลของผู้ใช้

  1. สร้าง ActionCodeSettings วัตถุซึ่งมี Firebase มีคำแนะนำเกี่ยวกับวิธีการสร้างการเชื่อมโยงอีเมล ตั้งค่าฟิลด์ต่อไปนี้:

    • url: ลิงก์ในรายละเอียดที่จะฝังและสถานะเพิ่มเติมที่จะส่งต่อ โดเมนของลิงก์จะต้องอยู่ในรายการที่อนุญาตพิเศษในรายการ Firebase Console ของโดเมนที่ได้รับอนุญาต ซึ่งสามารถพบได้โดยไปที่แท็บวิธีการลงชื่อเข้าใช้ (การตรวจสอบสิทธิ์ -> วิธีการลงชื่อเข้าใช้)
    • iOSBundleID และ androidPackageName : แอปที่จะใช้เมื่อเปิดลิงก์ลงชื่อเข้าใช้บนอุปกรณ์ Android หรือ Apple เรียนรู้เพิ่มเติมเกี่ยวกับวิธีการ กำหนดค่า Firebase แบบไดนามิกลิงค์ ที่จะเปิดการเชื่อมโยงการดำเนินการผ่านทางอีเมลปพลิเคชันมือถือ
    • handleCodeInApp: ตั้งค่าเป็นจริง การดำเนินการลงชื่อเข้าใช้จะต้องเสร็จสิ้นในแอปเสมอ ซึ่งแตกต่างจากการดำเนินการอีเมลนอกวงอื่นๆ (การรีเซ็ตรหัสผ่านและการยืนยันอีเมล) เนื่องจากเมื่อสิ้นสุดโฟลว์ ผู้ใช้จะต้องลงชื่อเข้าใช้และสถานะการตรวจสอบสิทธิ์จะคงอยู่ในแอป
    • dynamicLinkDomain: เมื่อโดเมนการเชื่อมโยงหลายแบบไดนามิกที่กำหนดเองที่กำหนดไว้สำหรับโครงการให้ระบุที่หนึ่งที่จะใช้เมื่อการเชื่อมโยงที่จะเปิดผ่านทาง app มือถือที่กำหนด (เช่น example.page.link ) มิฉะนั้น โดเมนแรกจะถูกเลือกโดยอัตโนมัติ

    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")
    

    วัตถุประสงค์-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")
        // ...
    }
    

    วัตถุประสงค์-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 ใช้ลิงก์แบบไดนามิกของ Firebase เพื่อส่งลิงก์อีเมลไปยังอุปกรณ์เคลื่อนที่ สำหรับการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ผ่านแอปพลิเคชันมือถือ แอปพลิเคชันต้องได้รับการกำหนดค่าให้ตรวจหาลิงก์แอปพลิเคชันที่เข้ามา แยกวิเคราะห์ลิงก์ในรายละเอียด จากนั้นลงชื่อเข้าใช้ให้เสร็จสิ้น

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

  1. เปิดใช้งานลิงก์แบบไดนามิกของ Firebase:

    1. ใน คอนโซล Firebase เปิดส่วนแบบไดนามิกลิงค์
    2. หากคุณยังไม่ได้ยอมรับข้อกำหนด Dynamic Links และสร้างโดเมน Dynamic Links ให้ดำเนินการทันที

      หากคุณสร้างโดเมนไดนามิกลิงก์แล้ว โปรดจำไว้ โดเมนลิงก์แบบไดนามิกมักจะดูเหมือนตัวอย่างต่อไปนี้:

      example.page.link

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

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

    1. หากคุณวางแผนที่จะจัดการลิงก์เหล่านี้จากแอปพลิเคชันของคุณ คุณต้องระบุรหัสบันเดิลในการตั้งค่าโปรเจ็กต์ Firebase Console นอกจากนี้ ต้องระบุ App Store ID และ Apple Developer Team ID ด้วย
    2. คุณจะต้องกำหนดค่าโดเมนตัวจัดการการดำเนินการอีเมลของคุณเป็นโดเมนที่เกี่ยวข้องในความสามารถของแอปพลิเคชันของคุณ โดยค่าเริ่มต้นจัดการการดำเนินการอีเมลถูกโฮสต์ในโดเมนเช่นตัวอย่างต่อไปนี้:
      APP_ID.firebaseapp.com
    3. หากคุณวางแผนที่จะเผยแพร่แอปพลิเคชันของคุณไปยัง iOS เวอร์ชัน 8 หรือต่ำกว่า คุณจะต้องตั้งค่า ID ชุดของคุณเป็นรูปแบบที่กำหนดเองสำหรับ URL ขาเข้า
    4. สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้หมายถึง การรับแพลตฟอร์มแอปเปิ้ลคำแนะนำแบบไดนามิกลิงค์

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

Swift

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

วัตถุประสงค์-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.
  }

วัตถุประสงค์-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.
  }

วัตถุประสงค์-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 ของผู้ใช้

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

Swift

 // After asking the user for their email.
 Auth.auth().fetchSignInMethods(forEmail: email) { signInMethods, error in
   // This returns the same array as fetchProviders(forEmail:completion:) but for email
   // provider identified by 'password' string, signInMethods would contain 2
   // different strings:
   // 'emailLink' if the user previously signed in with an email/link
   // 'password' if the user has a password.
   // A user could have both.
   if (error) {
     // Handle error case.
   }
   if (!signInMethods.contains(EmailPasswordAuthSignInMethod)) {
     // User can sign in with email/password.
   }
   if (!signInMethods.contains(EmailLinkAuthSignInMethod)) {
     // User can sign in with email/link.
   }
 }

วัตถุประสงค์-C

 // After asking the user for their email.
 [FIRAuth auth] fetchSignInMethodsForEmail:email
                                completion:^(NSArray *_Nullable signInMethods,
                                             NSError *_Nullable error) {
   // This returns the same array as fetchProvidersForEmail but for email
   // provider identified by 'password' string, signInMethods would contain 2
   // different strings:
   // 'emailLink' if the user previously signed in with an email/link
   // 'password' if the user has a password.
   // A user could have both.
   if (error) {
     // Handle error case.
   }
   if (![signInMethods containsObject:FIREmailPasswordAuthSignInMethod]) {
     // User can sign in with email/password.
   }
   if (![signInMethods containsObject:FIREmailLinkAuthSignInMethod]) {
     // User can sign in with email/link.
   }
 }];

ตามที่อธิบายไว้ข้างต้นอีเมล์ / รหัสผ่านและอีเมล์ลิงค์ / ได้รับการพิจารณาเดียวกัน FIREmailAuthProvider (เช่นเดียว PROVIDER_ID ) ด้วยวิธีการที่แตกต่างกันของการลงชื่อเข้าใช้

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

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

  • ในปพลิเคชันของคุณคุณจะได้รับข้อมูลรายละเอียดของผู้ใช้พื้นฐานจาก FIRUser วัตถุ ดู การจัดการผู้ใช้

  • ในฐานข้อมูล Firebase เรียลไทม์และการจัดเก็บเมฆ กฎการรักษาความปลอดภัย , คุณจะได้รับการลงนามใน ID ผู้ใช้ของผู้ใช้ที่ไม่ซ้ำกันจาก auth ตัวแปรและใช้ในการควบคุมสิ่งที่ข้อมูลที่เข้าถึงผู้ใช้สามารถ

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

ออกจากระบบผู้ใช้โทร signOut:

Swift

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

วัตถุประสงค์-C

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

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