您可以使用 Firebase 驗證功能,向使用者傳送含有連結的電子郵件,讓他們點選即可登入。在過程中,系統也會驗證使用者的電子郵件地址。
使用電子郵件登入有以下優點:
- 簡化註冊和登入程序。
- 降低應用程式之間重複使用密碼的風險,可能導致選取的密碼安全性不佳。
- 驗證使用者身分,同時驗證使用者是否為電子郵件地址的合法擁有者。
- 使用者只需具備可存取的電子郵件帳戶即可登入。不需要具備電話號碼或社群媒體帳戶的擁有權。
- 使用者不需提供 (或記住) 密碼,即可安全登入,這對行動裝置來說可能很麻煩。
- 先前以電子郵件 ID (密碼或聯合) 登入的現有使用者之升級,可以升級到僅使用電子郵件登入。舉例來說,如果使用者忘記密碼,仍然可以在不需要重設密碼的情況下登入。
事前準備
使用 Swift Package Manager 安裝及管理 Firebase 依附元件。
- 在 Xcode 中保持開啟應用程式專案,然後依序點選「File」>「Add Packages」。
- 在系統提示時,新增 Firebase Apple 平台 SDK 存放區:
- 選擇 Firebase 驗證資料庫。
- 在目標建構設定的「Other Linker Flags」部分中新增
-ObjC
標記。 - 完成後,Xcode 會自動開始在背景解析並下載依附元件。
https://github.com/firebase/firebase-ios-sdk.git
為 Firebase 專案啟用電子郵件連結登入功能
如要透過電子郵件連結登入使用者,您必須先為 Firebase 專案啟用電子郵件服務供應商和電子郵件連結登入方式:
- 在 Firebase 控制台開啟「Auth」專區。
- 在「Sign in method」分頁中啟用「Email/Password」供應商。請注意,您必須啟用電子郵件/密碼登入功能,才能使用電子郵件連結登入。
- 在相同區段中,啟用「Email link (無密碼登入)」登入方式。
- 點選「Save」。
傳送驗證連結至使用者的電子郵件地址
如要啟動驗證流程,請向使用者顯示一個可提示使用者提供電子郵件地址的介面,然後呼叫 sendSignInLink
以要求 Firebase 將驗證連結傳送至使用者的電子郵件。
建構
ActionCodeSettings
物件,向 Firebase 提供建構電子郵件連結的操作說明。設定下列欄位:- url:要嵌入的深層連結,以及要一併傳送的任何其他狀態。連結的網域必須在 Firebase 控制台的授權網域清單中加入許可清單,只要前往「登入方式」分頁 (依序點選「驗證」->「登入方式」),就能找到該網域。
- iOSBundleID 和 androidPackageName:在 Android 或 Apple 裝置上開啟登入連結時使用的應用程式。進一步瞭解如何設定 Firebase Dynamic Links,以透過行動應用程式開啟電子郵件動作連結。
- handleCodeInApp:設為 true。登入作業必須一律在應用程式中完成,這一點與頻帶其他電子郵件動作不同 (密碼重設和電子郵件驗證)。這是因為在流程結束時,使用者應會登入,且驗證狀態也會保留在應用程式中。
- DynamicLinkDomain:如果為專案定義了多個自訂動態連結網域,請指定當使用者透過指定的行動應用程式 (例如
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")
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,請參閱「電子郵件動作中的票證狀態」一節。
要求使用者提供電子郵件地址。
傳送驗證連結至使用者的電子郵件,並儲存使用者的電子郵件地址,以便在使用者在同一部裝置上完成電子郵件登入時使用。
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 驗證會使用 Firebase 動態連結將電子郵件連結傳送至行動裝置。如要透過行動應用程式完成登入,您必須將應用程式設為偵測傳入的應用程式連結,剖析基礎深層連結,然後完成登入程序。
設定 Firebase Dynamic Links
如果傳送的連結是專為行動應用程式開啟的連結,Firebase 驗證會使用 Firebase 動態連結。如要使用這項功能,您必須在 Firebase 控制台中設定 Dynamic Links。
啟用 Firebase Dynamic Links:
- 在 Firebase 控制台開啟「Dynamic Links」部分。
-
如果您尚未接受 Dynamic Links 條款,並且已建立 Dynamic Links 網域,請立即採取行動。
若您已建立 Dynamic Links 網域,請記下該網域。Dynamic Links 網域通常如以下範例所示:
example.page.link
將 Apple 或 Android 應用程式設為攔截傳入連結時,您需要用到這個值。
設定 Apple 應用程式:
- 如果您打算從應用程式處理這些連結,就必須在 Firebase 控制台的專案設定中指定軟體包 ID。此外,您也必須指定 App Store ID 和 Apple Developer Team ID。
- 您也必須在應用程式功能中,將電子郵件動作處理常式網域設為關聯網域。根據預設,電子郵件動作處理常式是由網域託管,範例如下:
APP_ID.firebaseapp.com
- 如果您打算將應用程式發行到 iOS 8 以下版本,則必須將軟體包 ID 設為傳入網址的自訂配置。
- 詳情請參閱接收 Apple 平台 Dynamic Links 操作說明。
驗證連結並登入
收到上述的連結後,請確認該連結是用於電子郵件連結驗證,並完成登入。
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 的資訊。
已淘汰:區分電子郵件密碼與電子郵件連結
如果專案在 2023 年 9 月 15 日當天或之後建立,系統預設會啟用電子郵件列舉防護功能。這項功能可改善專案使用者帳戶的安全性,但會停用 fetchSignInMethodsForEmail()
方法 (先前建議用於實作 ID 優先流程)。
雖然您可以停用專案的電子郵件列舉防護功能,但建議您不要這麼做。
詳情請參閱電子郵件列舉防護功能說明文件。
後續步驟
使用者首次登入時,系統會建立新的使用者帳戶,並連結至憑證 (即使用者名稱與密碼、電話號碼或驗證提供者資訊),也就是使用者登入時使用的憑證。這個新帳戶會儲存在您的 Firebase 專案中,可用來識別專案中各個應用程式的使用者 (無論使用者登入方式為何)。
在 Firebase 即時資料庫和 Cloud Storage 安全性規則中,您可以透過
auth
變數取得登入使用者的專屬 ID,並使用該 ID 控管使用者可存取哪些資料。
您可以將驗證供應商憑證連結至現有的使用者帳戶,讓使用者透過多個驗證服務提供者登入您的應用程式。
如要登出使用者,請呼叫
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; }
您可能也想要針對各種驗證錯誤加入錯誤處理程式碼。請參閱處理錯誤。