Вы можете использовать аутентификацию Firebase для входа пользователя, отправив ему электронное письмо, содержащее ссылку, по которой он может щелкнуть, чтобы войти в систему. При этом также проверяется адрес электронной почты пользователя.
Вход в систему по электронной почте имеет множество преимуществ:
- Простая регистрация и вход.
- Снижение риска повторного использования паролей в приложениях, что может подорвать безопасность даже правильно выбранных паролей.
- Возможность аутентификации пользователя, а также проверка того, что пользователь является законным владельцем адреса электронной почты.
- Для входа в систему пользователю требуется только доступная учетная запись электронной почты. Никакого владения номером телефона или учетной записью в социальной сети не требуется.
- Пользователь может безопасно войти в систему без необходимости вводить (или запоминать) пароль, который может быть затруднительным на мобильном устройстве.
- Существующего пользователя, который ранее входил в систему с помощью идентификатора электронной почты (пароля или федеративного), можно обновить, чтобы он входил в систему только с помощью электронной почты. Например, пользователь, забывший свой пароль, все равно может войти в систему без необходимости его сброса.
Прежде чем начать
Используйте Swift Package Manager для установки зависимостей Firebase и управления ими.
- В Xcode, открыв проект приложения, выберите «Файл» > «Добавить пакеты» .
- При появлении запроса добавьте репозиторий Firebase SDK для платформ Apple:
- Выберите библиотеку Firebase Authentication .
- Добавьте флаг
-ObjC
в раздел «Другие флаги компоновщика» настроек сборки вашей цели. - По завершении Xcode автоматически начнет разрешать и загружать ваши зависимости в фоновом режиме.
https://github.com/firebase/firebase-ios-sdk.git
Включите вход по электронной почте для вашего проекта Firebase
Чтобы войти в систему по ссылке электронной почты, сначала необходимо включить поставщика электронной почты и метод входа по ссылке электронной почты для вашего проекта Firebase:
- В консоли Firebase откройте раздел Auth .
- На вкладке «Метод входа » включите поставщика электронной почты и пароля . Обратите внимание, что для использования входа по ссылке электронной почты необходимо включить вход по электронной почте и паролю.
- В том же разделе включите метод входа по ссылке электронной почты (вход без пароля) .
- Нажмите Сохранить .
Отправьте ссылку для аутентификации на адрес электронной почты пользователя.
Чтобы инициировать процесс аутентификации, предоставьте пользователю интерфейс, который предложит пользователю указать свой адрес электронной почты, а затем вызовите sendSignInLink
, чтобы запросить у Firebase отправку ссылки аутентификации на электронную почту пользователя.
Создайте объект
ActionCodeSettings
, который предоставит Firebase инструкции по созданию ссылки электронной почты. Задайте следующие поля:-
url
: глубокая ссылка для встраивания и любое дополнительное состояние, которое необходимо передать. Домен ссылки должен быть внесен в белый список авторизованных доменов консоли Firebase, который можно найти, перейдя на вкладку «Метод входа» (Аутентификация -> Метод входа). -
iOSBundleID
иandroidPackageName
: помогают Firebase Authentication определить, следует ли создавать ссылку только для Интернета или для мобильных устройств, которая открывается на устройстве Android или Apple. -
handleCodeInApp
: установлено значение true. Операцию входа в систему всегда необходимо выполнять в приложении, в отличие от других внешних действий с электронной почтой (сброс пароля и проверка электронной почты). Это связано с тем, что в конце потока ожидается, что пользователь войдет в систему, и его состояние аутентификации сохранится в приложении. -
linkDomain
: если для проекта определены пользовательские домены ссылок Hosting , укажите, какой из них использовать, когда ссылка должна открываться указанным мобильным приложением. В противном случае автоматически выбирается домен по умолчанию (например,PROJECT_ID .firebaseapp.com
). dynamicLinkDomain
: устарел. Не указывайте этот параметр.
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")
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
см. в разделе «Передача состояния в действиях по электронной почте» .-
Попросите пользователя указать адрес электронной почты. Отправьте ссылку для аутентификации на адрес электронной почты пользователя и сохраните адрес электронной почты пользователя на случай, если пользователь завершит вход в систему по электронной почте на том же устройстве. 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") // ... }
[[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"]; // ... }];
Завершите вход по ссылке электронной почты.
Проблемы безопасности
Завершение входа в мобильное приложение Apple
Настройка Firebase Hosting
Настройте домены Firebase Hosting : В консоли Firebase откройте раздел Хостинг . Если вы хотите использовать домен по умолчанию для ссылки электронной почты, которая открывается в мобильных приложениях, перейдите на сайт по умолчанию и запишите домен Hosting по умолчанию. Домен Hosting по умолчанию обычно выглядит следующим образом: PROJECT_ID .firebaseapp.com
.Это значение понадобится вам, когда вы настроите свое приложение для перехвата входящей ссылки. Если вы хотите использовать собственный домен для ссылки электронной почты, вы можете зарегистрировать его на Firebase Hosting и использовать его в качестве домена ссылки.
Настройка приложений Apple: Вам нужно будет настроить выбранный домен как связанный домен для ссылок на приложения. Чтобы настроить право в своем приложении, откройте вкладку «Подписание и возможности» цели в Xcode и добавьте домены хостинга Firebase из предыдущего шага к возможности «Связанные домены». Если вы используете домен Firebase Hosting по умолчанию, это будет applinks: PROJECT_ID .firebaseapp.com
.Дополнительную информацию см. в разделе «Поддержка связанных доменов» на сайте документации Apple.
Подтвердите ссылку и войдите в систему
if Auth.auth().isSignIn(withEmailLink: link) { Auth.auth().signIn(withEmail: email, link: self.link) { user, error in // ... } }
if ([[FIRAuth auth] isSignInWithEmailLink:link]) { [[FIRAuth auth] signInWithEmail:email link:link completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { // ... }]; }
Привязка/повторная аутентификация по ссылке электронной почты
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. }
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. }
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 Dynamic Links
Устарело: отличие пароля электронной почты от ссылки электронной почты.
fetchSignInMethodsForEmail()
, который мы ранее рекомендовали для реализации потоков с приоритетом идентификаторов.
Следующие шаги
В своих приложениях вы можете получить базовую информацию профиля пользователя из объекта User
. См. Управление пользователями .В правилах безопасности базы данных реального времени и Cloud Storage Firebase Realtime Database вы можете получить уникальный идентификатор пользователя, вошедшего в систему, из переменной auth
и использовать его для управления тем, к каким данным пользователь может получить доступ.
signOut:
.
let firebaseAuth = Auth.auth() do { try firebaseAuth.signOut() } catch let signOutError as NSError { print("Error signing out: %@", signOutError) }
NSError *signOutError; BOOL status = [[FIRAuth auth] signOut:&signOutError]; if (!status) { NSLog(@"Error signing out: %@", signOutError); return; }