Join us in person and online for Firebase Summit on October 18, 2022. Learn how Firebase can help you accelerate app development, release your app with confidence, and scale with ease. Register now

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

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

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

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

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

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

  1. Если вы еще этого не сделали, следуйте инструкциям в руководстве по началу работы.

  2. Включите вход по электронной почте для вашего проекта Firebase.

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

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

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

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

    • url : глубокая ссылка для встраивания и любое дополнительное состояние, которое необходимо передать. Домен ссылки должен быть внесен в белый список в списке авторизованных доменов Firebase Console, который можно найти, перейдя на вкладку «Метод входа» («Аутентификация» -> «Метод входа»). Ссылка перенаправит пользователя на этот URL-адрес, если приложение не установлено на его устройстве и установить его не удалось.

    • androidPackageName и IOSBundleId : приложения, используемые при открытии ссылки для входа на устройстве Android или iOS. Узнайте больше о том, как настроить динамические ссылки Firebase для открытия ссылок действий в электронной почте через мобильные приложения.

    • handleCodeInApp : установите значение true . Операция входа всегда должна выполняться в приложении, в отличие от других внеплановых действий с электронной почтой (сброс пароля и проверка электронной почты). Это связано с тем, что в конце потока ожидается, что пользователь войдет в систему, а его состояние аутентификации сохранится в приложении.

    • dynamicLinkDomain : если для проекта определено несколько настраиваемых доменов динамической ссылки, укажите, какой из них использовать, когда ссылка должна быть открыта через указанное мобильное приложение (например, example.page.link ). В противном случае автоматически выбирается первый домен.

    var acs = ActionCodeSettings(
        // URL you want to redirect back to. The domain (www.example.com) for this
        // URL must be whitelisted in the Firebase Console.
        url: 'https://www.example.com/finishSignUp?cartId=1234',
        // This must be true
        handleCodeInApp: true,
        iOSBundleId: 'com.example.ios',
        androidPackageName: 'com.example.android',
        // installIfNotAvailable
        androidInstallApp: true,
        // minimumVersion
        androidMinimumVersion: '12');
    
  2. Спросите у пользователя адрес электронной почты.

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

    var emailAuth = 'someemail@domain.com';
    FirebaseAuth.instance.sendSignInLinkToEmail(
            email: emailAuth, actionCodeSettings: acs)
        .catchError((onError) => print('Error sending email verification $onError'))
        .then((value) => print('Successfully sent email verification'));
    });
    

Вопросы безопасности

Чтобы предотвратить использование ссылки для входа в качестве непреднамеренного пользователя или на непредусмотренном устройстве, Firebase Auth требует предоставления адреса электронной почты пользователя при завершении процесса входа. Для успешного входа этот адрес электронной почты должен совпадать с адресом, на который изначально была отправлена ​​ссылка для входа.

Вы можете оптимизировать этот процесс для пользователей, которые открывают ссылку для входа на том же устройстве, на котором они запрашивают ссылку, сохраняя их адрес электронной почты локально (например, с помощью SharedPreferences) при отправке сообщения электронной почты для входа. Затем используйте этот адрес для завершения потока. Не передавайте адрес электронной почты пользователя в параметрах URL-адреса перенаправления и не используйте его повторно, так как это может привести к внедрению сеансовых инъекций.

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

Также убедитесь, что вы используете URL-адрес HTTPS в рабочей среде, чтобы избежать потенциального перехвата вашей ссылки промежуточными серверами.

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

  1. Настройте свое приложение для получения динамических ссылок на Flutter в руководстве .

  2. В обработчике ссылок проверьте, предназначена ли ссылка для аутентификации по ссылке электронной почты, и если да, завершите процесс входа.

    // Confirm the link is a sign-in with email link.
    if (FirebaseAuth.instance.isSignInWithEmailLink(emailLink)) {
      try {
        // The client SDK will parse the code from the link for you.
        final userCredential = await FirebaseAuth.instance
            .signInWithEmailLink(email: emailAuth, emailLink: emailLink);
    
        // You can access the new user via userCredential.user.
        final emailAddress = userCredential.user?.email;
    
        print('Successfully signed in with email link!');
      } catch (error) {
        print('Error signing in with email link.');
      }
    }
    

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

Разница будет во второй половине операции:

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.linkWithCredential(authCredential);
} catch (error) {
    print("Error linking emailLink credential.");
}

Это также можно использовать для повторной аутентификации пользователя ссылки электронной почты перед выполнением конфиденциальной операции.

final authCredential = EmailAuthProvider
    .credentialWithLink(email: emailAuth, emailLink: emailLink.toString());
try {
    await FirebaseAuth.instance.currentUser
        ?.reauthenticateWithCredential(authCredential);
} catch (error) {
    print("Error reauthenticating credential.");
}

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

Если вы поддерживаете вход по электронной почте как по паролю, так и по ссылке, чтобы различать метод входа для пользователя по паролю/ссылке, используйте fetchSignInMethodsForEmail . Это полезно для потоков с идентификатором в первую очередь, когда пользователя сначала просят указать адрес электронной почты, а затем предлагают метод входа:

try {
    final signInMethods =
        await FirebaseAuth.instance.fetchSignInMethodsForEmail(emailAuth);
    final userExists = signInMethods.isNotEmpty;
    final canSignInWithLink = signInMethods
        .contains(EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD);
    final canSignInWithPassword = signInMethods
        .contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD);
} on FirebaseAuthException catch (exception) {
    switch (exception.code) {
        case "invalid-email":
            print("Not a valid email address.");
            break;
        default:
            print("Unknown error.");
    }
}

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

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

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

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

В правилах безопасности Firebase Realtime Database и Cloud Storage вы можете получить уникальный идентификатор вошедшего пользователя из переменной auth и использовать его для управления тем, к каким данным пользователь может получить доступ.

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

Чтобы выйти из системы, вызовите signOut() :

await FirebaseAuth.instance.signOut();