คุณสามารถใช้การตรวจสอบความถูกต้องของ Firebase เพื่อลงชื่อเข้าใช้ผู้ใช้โดยส่งอีเมลที่มีลิงก์ให้ผู้ใช้คลิกเพื่อลงชื่อเข้าใช้ ในขั้นตอนนี้ ที่อยู่อีเมลของผู้ใช้จะได้รับการยืนยันด้วย
มีประโยชน์มากมายในการลงชื่อเข้าใช้ด้วยอีเมล:
- การลงทะเบียนและการลงชื่อเข้าใช้ที่มีแรงเสียดทานต่ำ
- ลดความเสี่ยงของการใช้รหัสผ่านซ้ำในแอปพลิเคชัน ซึ่งอาจทำลายความปลอดภัยของรหัสผ่านที่เลือกมาอย่างดี
- ความสามารถในการรับรองความถูกต้องของผู้ใช้ในขณะเดียวกันก็ยืนยันว่าผู้ใช้เป็นเจ้าของที่อยู่อีเมลที่ถูกต้องตามกฎหมาย
- ผู้ใช้ต้องการเพียงบัญชีอีเมลที่สามารถเข้าถึงได้เพื่อลงชื่อเข้าใช้ ไม่จำเป็นต้องเป็นเจ้าของหมายเลขโทรศัพท์หรือบัญชีโซเชียลมีเดีย
- ผู้ใช้สามารถลงชื่อเข้าใช้ได้อย่างปลอดภัยโดยไม่จำเป็นต้องระบุ (หรือจำ) รหัสผ่าน ซึ่งอาจเป็นเรื่องยุ่งยากบนอุปกรณ์พกพา
- ผู้ใช้ปัจจุบันที่ลงชื่อเข้าใช้ด้วยตัวระบุอีเมล (รหัสผ่านหรือส่วนกลาง) สามารถอัปเกรดเพื่อลงชื่อเข้าใช้ด้วยอีเมลเพียงอย่างเดียว ตัวอย่างเช่น ผู้ใช้ที่ลืมรหัสผ่านยังสามารถลงชื่อเข้าใช้ได้โดยไม่จำเป็นต้องรีเซ็ตรหัสผ่าน
ก่อนที่คุณจะเริ่มต้น
ใช้ Swift Package Manager เพื่อติดตั้งและจัดการการอ้างอิง Firebase
- ใน Xcode เมื่อโปรเจ็กต์แอปของคุณเปิดอยู่ ให้ไปที่ File > Add Packages
- เมื่อได้รับแจ้ง ให้เพิ่มที่เก็บ Firebase Apple platforms SDK:
- เลือกไลบรารีการรับรองความถูกต้องของ Firebase
- เมื่อเสร็จแล้ว Xcode จะเริ่มแก้ไขและดาวน์โหลดการอ้างอิงของคุณโดยอัตโนมัติในเบื้องหลัง
https://github.com/firebase/firebase-ios-sdk
เปิดใช้งานการลงชื่อเข้าใช้ลิงก์อีเมลสำหรับโครงการ Firebase ของคุณ
ในการลงชื่อเข้าใช้ผู้ใช้ด้วยลิงก์อีเมล คุณต้องเปิดใช้ผู้ให้บริการอีเมลและวิธีการลงชื่อเข้าใช้ลิงก์อีเมลสำหรับโปรเจ็กต์ Firebase ของคุณก่อน:
- ใน คอนโซล Firebase ให้เปิดส่วน การรับรองความถูกต้อง
- บนแท็บ วิธีการลงชื่อเข้า ใช้ ให้เปิดใช้งานผู้ให้บริการ อีเมล/รหัสผ่าน โปรดทราบว่าต้องเปิดใช้งานการลงชื่อเข้าใช้ด้วยอีเมล/รหัสผ่านเพื่อใช้การลงชื่อเข้าใช้ด้วยลิงก์อีเมล
- ในส่วนเดียวกัน ให้เปิดใช้งานวิธีการลงชื่อเข้า ใช้ด้วยลิงก์อีเมล (ลงชื่อเข้าใช้แบบไม่ใช้รหัสผ่าน)
- คลิก บันทึก
ส่งลิงก์การตรวจสอบสิทธิ์ไปยังที่อยู่อีเมลของผู้ใช้
ในการเริ่มต้นโฟลว์การตรวจสอบสิทธิ์ ให้แสดงอินเทอร์เฟซที่แจ้งให้ผู้ใช้ระบุที่อยู่อีเมล จากนั้นเรียก sendSignInLink
เพื่อขอให้ Firebase ส่งลิงก์การตรวจสอบสิทธิ์ไปยังอีเมลของผู้ใช้
สร้างวัตถุ
ActionCodeSettings
ซึ่งให้ Firebase พร้อมคำแนะนำเกี่ยวกับวิธีสร้างลิงก์อีเมล ตั้งค่าฟิลด์ต่อไปนี้:- url: ลิงก์ในรายละเอียดเพื่อฝังและสถานะเพิ่มเติมที่จะส่งต่อ โดเมนของลิงก์ต้องได้รับการอนุญาตพิเศษในรายการคอนโซล Firebase ของโดเมนที่ได้รับอนุญาต ซึ่งสามารถดูได้โดยไปที่แท็บวิธีการลงชื่อเข้าใช้ (การตรวจสอบสิทธิ์ -> วิธีการลงชื่อเข้าใช้)
- iOSBundleID และ androidPackageName : แอปที่จะใช้เมื่อเปิดลิงก์ลงชื่อเข้าใช้บนอุปกรณ์ Android หรือ Apple เรียนรู้เพิ่มเติมเกี่ยวกับวิธี กำหนดค่า Firebase Dynamic Links เพื่อเปิดลิงก์การดำเนินการทางอีเมลผ่านแอปบนอุปกรณ์เคลื่อนที่
- handleCodeInApp: ตั้งค่าเป็นจริง การดำเนินการลงชื่อเข้าใช้จะต้องเสร็จสิ้นในแอปเสมอซึ่งแตกต่างจากการดำเนินการทางอีเมลอื่น ๆ (การรีเซ็ตรหัสผ่านและการยืนยันอีเมล) นี่เป็นเพราะเมื่อสิ้นสุดโฟลว์ ผู้ใช้คาดว่าจะลงชื่อเข้าใช้และสถานะการรับรองความถูกต้องยังคงอยู่ในแอป
- dynamicLinkDomain: เมื่อมีการกำหนดโดเมนลิงก์แบบไดนามิกที่กำหนดเองหลายโดเมนสำหรับโครงการ ให้ระบุว่าจะใช้โดเมนใดเมื่อจะเปิดลิงก์ผ่านแอปบนอุปกรณ์เคลื่อนที่ที่ระบุ (เช่น
example.page.link
) มิฉะนั้น โดเมนแรกจะถูกเลือกโดยอัตโนมัติ
สวิฟต์
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 โปรดดูที่ Passing State ในส่วน Email Actions
ขออีเมลจากผู้ใช้
ส่งลิงก์การตรวจสอบสิทธิ์ไปยังอีเมลของผู้ใช้ และบันทึกอีเมลของผู้ใช้ในกรณีที่ผู้ใช้ลงชื่อเข้าใช้อีเมลในอุปกรณ์เดียวกัน
สวิฟต์
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 Authentication ใช้ Firebase Dynamic Links เพื่อส่งลิงก์อีเมลไปยังอุปกรณ์เคลื่อนที่ สำหรับการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ผ่านแอปพลิเคชันมือถือ แอปพลิเคชันจะต้องได้รับการกำหนดค่าให้ตรวจหาลิงก์แอปพลิเคชันที่เข้ามา แยกวิเคราะห์ลิงก์ในรายละเอียด จากนั้นจึงทำการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์
การกำหนดค่าลิงก์ไดนามิกของ Firebase
Firebase Auth ใช้ Firebase Dynamic Links เมื่อส่งลิงก์ที่ต้องการเปิดในแอปพลิเคชันมือถือ หากต้องการใช้ฟีเจอร์นี้ ลิงก์แบบไดนามิกต้องได้รับการกำหนดค่าในคอนโซล Firebase
เปิดใช้ลิงก์ไดนามิกของ Firebase:
- ใน คอนโซล Firebase ให้เปิดส่วน ลิงก์แบบไดนามิก
หากคุณยังไม่ได้ยอมรับข้อกำหนดของ Dynamic Links และสร้างโดเมน Dynamic Links ให้ดำเนินการทันที
หากคุณสร้างโดเมนลิงก์แบบไดนามิกแล้ว โปรดจดบันทึกไว้ โดยทั่วไปแล้วโดเมนลิงก์แบบไดนามิกจะมีลักษณะดังนี้:
example.page.link
คุณจะต้องใช้ค่านี้เมื่อคุณกำหนดค่าแอป Apple หรือ Android เพื่อสกัดกั้นลิงก์ขาเข้า
การกำหนดค่าแอปพลิเคชัน Apple:
- หากคุณวางแผนที่จะจัดการลิงก์เหล่านี้จากแอปพลิเคชันของคุณ จะต้องระบุรหัสบันเดิลในการตั้งค่าโปรเจ็กต์คอนโซล Firebase นอกจากนี้ จำเป็นต้องระบุ ID ของ App Store และ Apple Developer Team ID ด้วย
- คุณจะต้องกำหนดค่าโดเมนตัวจัดการการดำเนินการอีเมลของคุณเป็นโดเมนที่เชื่อมโยงในความสามารถของแอปพลิเคชันของคุณ ตามค่าเริ่มต้น ตัวจัดการการดำเนินการอีเมลจะโฮสต์บนโดเมนดังตัวอย่างต่อไปนี้:
APP_ID.firebaseapp.com
- หากคุณวางแผนที่จะเผยแพร่แอปพลิเคชันของคุณไปยัง iOS เวอร์ชัน 8 หรือต่ำกว่า คุณจะต้องตั้งค่า Bundle ID เป็นแบบแผนที่กำหนดเองสำหรับ URL ขาเข้า
- สำหรับข้อมูลเพิ่มเติม โปรดดู คำแนะนำในการรับลิงก์แบบไดนามิกของแพลตฟอร์ม Apple
ตรวจสอบลิงก์และลงชื่อเข้าใช้
หลังจากที่คุณได้รับลิงก์ตามที่อธิบายไว้ข้างต้น ให้ตรวจสอบว่ามีไว้สำหรับการตรวจสอบสิทธิ์ลิงก์อีเมลและลงชื่อเข้าใช้ให้เสร็จสมบูรณ์
สวิฟต์
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
หากต้องการเรียนรู้เกี่ยวกับวิธีจัดการกับการลงชื่อเข้าใช้ด้วยลิงก์อีเมลในเว็บแอปพลิเคชัน โปรดดู คู่มือเว็บ
การเชื่อมโยง / ตรวจสอบความถูกต้องอีกครั้งด้วยลิงก์อีเมล
คุณยังสามารถเชื่อมโยงวิธีการรับรองความถูกต้องนี้กับผู้ใช้ที่มีอยู่ ตัวอย่างเช่น ผู้ใช้ที่เคยตรวจสอบสิทธิ์กับผู้ให้บริการรายอื่น เช่น หมายเลขโทรศัพท์ สามารถเพิ่มวิธีการลงชื่อเข้าใช้นี้ในบัญชีที่มีอยู่ได้
ความแตกต่างจะอยู่ในช่วงครึ่งหลังของการดำเนินการ:
สวิฟต์
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. }];
นอกจากนี้ยังสามารถใช้เพื่อตรวจสอบสิทธิ์ผู้ใช้ลิงก์อีเมลอีกครั้งก่อนที่จะเรียกใช้การดำเนินการที่ละเอียดอ่อน
สวิฟต์
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
ซึ่งมีประโยชน์สำหรับโฟลว์ที่ใช้ตัวระบุเป็นอันดับแรก ซึ่งผู้ใช้จะถูกขอให้ระบุอีเมลก่อน จากนั้นจึงนำเสนอวิธีการลงชื่อเข้าใช้:
สวิฟต์
// 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. } }];
ตามที่อธิบายไว้ข้างต้น อีเมล/รหัสผ่าน และ อีเมล/ลิงก์ ถือเป็น EmailAuthProvider
เดียวกัน ( PROVIDER_ID
เดียวกัน) โดยมีวิธีการลงชื่อเข้าใช้ต่างกัน
ขั้นตอนถัดไป
หลังจากที่ผู้ใช้ลงชื่อเข้าใช้เป็นครั้งแรก บัญชีผู้ใช้ใหม่จะถูกสร้างขึ้นและเชื่อมโยงกับข้อมูลประจำตัว ซึ่งก็คือชื่อผู้ใช้และรหัสผ่าน หมายเลขโทรศัพท์ หรือข้อมูลผู้ให้บริการตรวจสอบสิทธิ์ ซึ่งผู้ใช้ลงชื่อเข้าใช้ด้วย บัญชีใหม่นี้จัดเก็บเป็นส่วนหนึ่งของโปรเจ็กต์ Firebase และสามารถใช้ระบุผู้ใช้ในทุกแอปในโครงการ ไม่ว่าผู้ใช้จะลงชื่อเข้าใช้ด้วยวิธีใดก็ตาม
ในแอปของคุณ คุณสามารถรับข้อมูลโปรไฟล์พื้นฐานของผู้ใช้ได้จากวัตถุ
User
ดู จัดการผู้ใช้ใน กฎความปลอดภัย ของ Firebase Realtime Database และ Cloud Storage คุณสามารถรับ ID ผู้ใช้ที่ไม่ซ้ำกันของผู้ใช้ที่ลงชื่อเข้าใช้จากตัวแปร
auth
และใช้เพื่อควบคุมข้อมูลที่ผู้ใช้สามารถเข้าถึงได้
คุณสามารถอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้แอปของคุณโดยใช้ผู้ให้บริการตรวจสอบสิทธิ์หลายรายโดย เชื่อมโยงข้อมูลประจำตัวของผู้ให้บริการตรวจสอบสิทธิ์กับบัญชีผู้ใช้ที่มีอยู่
หากต้องการออกจากระบบผู้ใช้ ให้เรียก signOut:
สวิฟต์
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; }
คุณอาจต้องการเพิ่มรหัสการจัดการข้อผิดพลาดสำหรับข้อผิดพลาดการตรวจสอบสิทธิ์ทั้งหมด ดู จัดการข้อผิดพลาด