Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Аутентификация с помощью Firebase с использованием ссылки электронной почты на платформах Apple

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Вы можете использовать Firebase Authentication для входа пользователя, отправив ему электронное письмо, содержащее ссылку, по которой он может щелкнуть, чтобы войти. В процессе также проверяется адрес электронной почты пользователя.

Вход по электронной почте имеет множество преимуществ:

  • Регистрация и вход с низким коэффициентом трения.
  • Меньший риск повторного использования пароля в разных приложениях, что может подорвать безопасность даже хорошо подобранных паролей.
  • Возможность аутентифицировать пользователя, а также подтверждать, что пользователь является законным владельцем адреса электронной почты.
  • Пользователю нужна только доступная учетная запись электронной почты для входа в систему. Владение номером телефона или учетной записью в социальных сетях не требуется.
  • Пользователь может безопасно войти в систему без необходимости вводить (или запоминать) пароль, что может быть громоздко на мобильном устройстве.
  • Существующий пользователь, который ранее входил в систему с идентификатором электронной почты (пароль или федерация), может быть обновлен, чтобы входить только с электронной почтой. Например, пользователь, который забыл свой пароль, все еще может войти в систему, не сбрасывая пароль.

Прежде чем вы начнете

Используйте Swift Package Manager для установки и управления зависимостями Firebase.

  1. В Xcode при открытом проекте приложения перейдите в File > Add Packages .
  2. При появлении запроса добавьте репозиторий SDK Firebase для платформ Apple:
  3.   https://github.com/firebase/firebase-ios-sdk
  4. Выберите библиотеку аутентификации Firebase.
  5. Когда закончите, Xcode автоматически начнет разрешать и загружать ваши зависимости в фоновом режиме.

Чтобы входить в систему по ссылке электронной почты, вы должны сначала включить поставщика электронной почты и метод входа по ссылке электронной почты для своего проекта Firebase:

  1. В консоли Firebase откройте раздел Auth .
  2. На вкладке « Метод входа » включите поставщика электронной почты/пароля . Обратите внимание, что для входа по электронной почте необходимо включить вход по электронной почте/паролю.
  3. В том же разделе включите метод входа по ссылке электронной почты (вход без пароля) .
  4. Нажмите Сохранить .

Чтобы инициировать процесс аутентификации, предоставьте пользователю интерфейс, который предлагает пользователю указать свой адрес электронной почты, а затем вызовите sendSignInLinkToEmail:actionCodeSettings:completion: чтобы запросить, чтобы Firebase отправила ссылку для аутентификации на электронную почту пользователя.

  1. Создайте объект ActionCodeSettings , который предоставит Firebase инструкции по созданию ссылки электронной почты. Задайте следующие поля:

    • url: глубокая ссылка для встраивания и любое дополнительное состояние, которое необходимо передать. Домен ссылки должен быть внесен в белый список в списке авторизованных доменов Firebase Console, который можно найти, перейдя на вкладку «Метод входа» («Аутентификация» -> «Метод входа»).
    • iOSBundleID и androidPackageName : приложения, используемые при открытии ссылки для входа на устройстве Android или Apple. Узнайте больше о том, как настроить динамические ссылки Firebase для открытия ссылок действий в электронной почте через мобильные приложения.
    • handleCodeInApp: установите значение true. Операция входа всегда должна выполняться в приложении, в отличие от других внеплановых действий с электронной почтой (сброс пароля и проверка электронной почты). Это связано с тем, что в конце потока ожидается, что пользователь войдет в систему, а его состояние аутентификации сохранится в приложении.
    • 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, обратитесь к разделу Состояние передачи в действиях по электронной почте .

  2. Спросите у пользователя адрес электронной почты.

  3. Отправьте ссылку для проверки подлинности на электронную почту пользователя и сохраните электронную почту пользователя на случай, если пользователь завершит вход по электронной почте на том же устройстве.

    Быстрый

    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 откройте раздел Dynamic Links .
    2. Если вы еще не приняли условия динамических ссылок и не создали домен динамических ссылок, сделайте это сейчас.

      Если вы уже создали домен динамических ссылок, обратите на это внимание. Домен динамических ссылок обычно выглядит следующим образом:

      example.page.link

      Это значение понадобится вам при настройке приложения Apple или Android для перехвата входящей ссылки.

  2. Настройка приложений Apple:

    1. Если вы планируете обрабатывать эти ссылки из своего приложения, необходимо указать идентификатор пакета в настройках проекта Firebase Console. Кроме того, необходимо указать идентификатор App Store и идентификатор команды разработчиков Apple.
    2. Вам также потребуется настроить домен обработчика действий электронной почты как связанный домен в возможностях вашего приложения. По умолчанию обработчик действий электронной почты размещается в домене, как показано в следующем примере:
      APP_ID.firebaseapp.com
      .
    3. Если вы планируете распространять свое приложение на iOS версии 8 и ниже, вам нужно будет установить идентификатор пакета в качестве пользовательской схемы для входящих URL-адресов.
    4. Для получения дополнительной информации см. инструкции по получению динамических ссылок платформы 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.
  }];

Однако, поскольку поток может закончиться на другом устройстве, на котором первоначальный пользователь не вошел в систему, этот поток может не завершиться. В этом случае пользователю может быть показано сообщение об ошибке, чтобы заставить его открыть ссылку на том же устройстве. Некоторое состояние может быть передано в ссылке, чтобы предоставить информацию о типе операции и пользовательском идентификаторе пользователя.

Если вы поддерживаете вход на основе пароля и ссылки с помощью электронной почты, чтобы различать метод входа для пользователя с паролем/ссылкой, используйте 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.
   }
 }];

Как описано выше, адрес электронной почты/пароль и адрес электронной почты/ссылка считаются одним и тем же FIREmailAuthProvider (один и тот же PROVIDER_ID ) с разными методами входа.

Следующие шаги

После того, как пользователь входит в систему в первый раз, создается новая учетная запись пользователя и связывается с учетными данными, т. е. с именем пользователя и паролем, номером телефона или информацией о поставщике проверки подлинности, с которыми пользователь вошел в систему. Эта новая учетная запись хранится как часть вашего проекта Firebase и может использоваться для идентификации пользователя во всех приложениях вашего проекта, независимо от того, как пользователь входит в систему.

  • В ваших приложениях вы можете получить основную информацию о профиле пользователя из объекта FIRUser . См. Управление пользователями .

  • В правилах безопасности базы данных реального времени и облачного хранилища Firebase вы можете получить уникальный идентификатор пользователя, вошедшего в систему, из переменной 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;
}

Вы также можете добавить код обработки ошибок для всего диапазона ошибок аутентификации. См. Обработка ошибок .