Аутентификация в Firebase по номеру телефона с использованием JavaScript,Аутентификация в Firebase по номеру телефона с помощью JavaScript

Вы можете использовать аутентификацию Firebase для входа в систему, отправив SMS-сообщение на телефон пользователя. Пользователь авторизуется с помощью одноразового кода, содержащегося в SMS-сообщении.

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

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

Если вы еще этого не сделали, скопируйте фрагмент инициализации из консоли Firebase в свой проект, как описано в разделе Добавление Firebase в проект JavaScript .

Проблемы безопасности

Аутентификация с использованием только номера телефона хоть и удобна, но менее безопасна, чем другие доступные методы, поскольку владение номером телефона может легко передаваться между пользователями. Кроме того, на устройствах с несколькими профилями пользователей любой пользователь, который может получать SMS-сообщения, может войти в учетную запись, используя номер телефона устройства.

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

Включите вход по номеру телефона для вашего проекта Firebase

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

  1. В консоли Firebase откройте раздел Аутентификация .
  2. На странице «Метод входа» включите метод входа по номеру телефона .
  3. Если на той же странице домен, на котором будет размещено ваше приложение, не указан в разделе Домены перенаправления OAuth , добавьте свой домен.

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

Настройте верификатор reCAPTCHA

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

Вам не нужно вручную настраивать клиент reCAPTCHA; когда вы используете объект RecaptchaVerifier Firebase SDK, Firebase автоматически создает и обрабатывает все необходимые клиентские ключи и секреты.

Объект RecaptchaVerifier поддерживает невидимый reCAPTCHA , который часто может проверять пользователя, не требуя каких-либо действий со стороны пользователя, а также виджет reCAPTCHA, который всегда требует взаимодействия с пользователем для успешного завершения.

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

Web modular API

import { getAuth } from "firebase/auth";

const auth = getAuth();
auth.languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// auth.useDeviceLanguage();

Web namespaced API

firebase.auth().languageCode = 'it';
// To apply the default browser preference instead of explicitly setting it.
// firebase.auth().useDeviceLanguage();

Используйте невидимую reCAPTCHA

Чтобы использовать невидимую reCAPTCHA, создайте объект RecaptchaVerifier с параметром size , установленным на invisible , указав идентификатор кнопки, которая отправляет вашу форму входа. Например:

Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Web namespaced API

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('sign-in-button', {
  'size': 'invisible',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    onSignInSubmit();
  }
});

Используйте виджет reCAPTCHA

Чтобы использовать видимый виджет reCAPTCHA, создайте на своей странице элемент, содержащий виджет, а затем создайте объект RecaptchaVerifier , указав при этом идентификатор контейнера. Например:

Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {});

Web namespaced API

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');

Необязательно: укажите параметры reCAPTCHA.

При желании вы можете установить функции обратного вызова для объекта RecaptchaVerifier , которые вызываются, когда пользователь решает reCAPTCHA или истечет срок действия reCAPTCHA до того, как пользователь отправит форму:

Web modular API

import { getAuth, RecaptchaVerifier } from "firebase/auth";

const auth = getAuth();
window.recaptchaVerifier = new RecaptchaVerifier(auth, 'recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Web namespaced API

window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container', {
  'size': 'normal',
  'callback': (response) => {
    // reCAPTCHA solved, allow signInWithPhoneNumber.
    // ...
  },
  'expired-callback': () => {
    // Response expired. Ask user to solve reCAPTCHA again.
    // ...
  }
});

Необязательно: предварительная обработка reCAPTCHA

Если вы хотите предварительно отобразить reCAPTCHA перед отправкой запроса на вход, вызовите render :

Web modular API

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

Web namespaced API

recaptchaVerifier.render().then((widgetId) => {
  window.recaptchaWidgetId = widgetId;
});

После render вы получаете идентификатор виджета reCAPTCHA, который можно использовать для вызовов API reCAPTCHA :

Web modular API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Web namespaced API

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Отправьте код подтверждения на телефон пользователя

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

  1. Получите номер телефона пользователя.

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

  2. Вызовите signInWithPhoneNumber , передав ему номер телефона пользователя и созданный ранее RecaptchaVerifier .

    Web modular API

    import { getAuth, signInWithPhoneNumber } from "firebase/auth";
    
    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    
    const auth = getAuth();
    signInWithPhoneNumber(auth, phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });

    Web namespaced API

    const phoneNumber = getPhoneNumberFromUserInput();
    const appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then((confirmationResult) => {
          // SMS sent. Prompt user to type the code from the message, then sign the
          // user in with confirmationResult.confirm(code).
          window.confirmationResult = confirmationResult;
          // ...
        }).catch((error) => {
          // Error; SMS not sent
          // ...
        });
    Если signInWithPhoneNumber приводит к ошибке, сбросьте reCAPTCHA, чтобы пользователь мог повторить попытку:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    });
    

Метод signInWithPhoneNumber выдает пользователю запрос reCAPTCHA, и если пользователь его принимает, запрашивает, чтобы Firebase Authentication отправила SMS-сообщение, содержащее код подтверждения, на телефон пользователя.

Войдите в систему с помощью проверочного кода.

После успешного вызова signInWithPhoneNumber предложите пользователю ввести код подтверждения, полученный по SMS. Затем войдите в систему пользователя, передав код методу confirm объекта ConfirmationResult , который был передан обработчику выполнения signInWithPhoneNumber (то then его блокированию). Например:

Web modular API

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Web namespaced API

const code = getCodeFromUserInput();
confirmationResult.confirm(code).then((result) => {
  // User signed in successfully.
  const user = result.user;
  // ...
}).catch((error) => {
  // User couldn't sign in (bad verification code?)
  // ...
});

Если вызов для confirm удался, пользователь успешно вошел в систему.

Получите промежуточный объект AuthCredential.

Если вам нужно получить объект AuthCredential для учетной записи пользователя, передайте код подтверждения из результата подтверждения и код подтверждения в PhoneAuthProvider.credential вместо вызова confirm :

var credential = firebase.auth.PhoneAuthProvider.credential(confirmationResult.verificationId, code);

Затем вы можете войти в систему с учетными данными:

firebase.auth().signInWithCredential(credential);

Тест с вымышленными телефонными номерами

Вы можете настроить вымышленные номера телефонов для разработки через консоль Firebase. Тестирование с использованием вымышленных телефонных номеров дает следующие преимущества:

  • Проверьте аутентификацию номера телефона, не расходуя квоту использования.
  • Проверьте аутентификацию номера телефона без отправки реального SMS-сообщения.
  • Запускайте последовательные тесты с одним и тем же номером телефона без ограничений. Это сводит к минимуму риск отклонения во время проверки в магазине приложений, если рецензент использует для тестирования один и тот же номер телефона.
  • Легко тестируйте в средах разработки без каких-либо дополнительных усилий, таких как возможность разработки в симуляторе iOS или эмуляторе Android без сервисов Google Play.
  • Создавайте интеграционные тесты, не блокируясь проверками безопасности, которые обычно применяются к реальным телефонным номерам в производственной среде.

Вымышленные номера телефонов должны соответствовать следующим требованиям:

  1. Убедитесь, что вы используете номера телефонов, которые действительно вымышлены и еще не существуют. Аутентификация Firebase не позволяет вам устанавливать существующие номера телефонов, используемые реальными пользователями, в качестве тестовых номеров. Один из вариантов — использовать номера с префиксом 555 в качестве тестовых телефонных номеров в США, например: +1 650-555-3434 .
  2. Номера телефонов должны быть правильно отформатированы с учетом длины и других ограничений. Они по-прежнему будут проходить ту же проверку, что и номер телефона реального пользователя.
  3. Для разработки можно добавить до 10 номеров телефонов.
  4. Используйте тестовые номера телефонов/коды, которые трудно угадать, и часто меняйте их.

Создавайте вымышленные номера телефонов и коды подтверждения.

  1. В консоли Firebase откройте раздел Аутентификация .
  2. На вкладке «Метод входа» включите поставщика услуг телефона, если вы еще этого не сделали.
  3. Откройте меню «Телефонные номера для тестирования аккордеона».
  4. Укажите номер телефона, который вы хотите протестировать, например: +1 650-555-3434 .
  5. Укажите шестизначный код подтверждения для этого конкретного номера, например: 654321 .
  6. Добавьте номер. Если есть необходимость, вы можете удалить номер телефона и его код, наведя курсор на соответствующую строку и нажав значок корзины.

Ручное тестирование

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

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

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

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

Интеграционное тестирование

Помимо ручного тестирования, Firebase Authentication предоставляет API, помогающие писать интеграционные тесты для тестирования аутентификации по телефону. Эти API отключают проверку приложений, отключив требование reCAPTCHA в Интернете и автоматические push-уведомления в iOS. Это делает возможным автоматизированное тестирование в этих потоках и упрощает его реализацию. Кроме того, они помогают обеспечить возможность тестирования потоков мгновенной проверки на Android.

В веб-версии установите для appVerificationDisabledForTesting значение true перед отрисовкой firebase.auth.RecaptchaVerifier . Это автоматически разрешает reCAPTCHA, позволяя вам передать номер телефона, не разгадывая его вручную. Обратите внимание: даже несмотря на то, что reCAPTCHA отключена, использование невымышленного номера телефона по-прежнему не позволит завершить вход. С этим API можно использовать только вымышленные номера телефонов.

// Turn off phone auth app verification.
firebase.auth().settings.appVerificationDisabledForTesting = true;

var phoneNumber = "+16505554567";
var testVerificationCode = "123456";

// This will render a fake reCAPTCHA as appVerificationDisabledForTesting is true.
// This will resolve after rendering without app verification.
var appVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
// signInWithPhoneNumber will call appVerifier.verify() which will resolve with a fake
// reCAPTCHA response.
firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
    .then(function (confirmationResult) {
      // confirmationResult can resolve with the fictional testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

Видимые и невидимые средства проверки приложений reCAPTCHA ведут себя по-разному, когда проверка приложений отключена:

  • Видимая reCAPTCHA : когда видимая reCAPTCHA отображается с помощью appVerifier.render() , она автоматически разрешается после задержки в доли секунды. Это эквивалентно тому, что пользователь нажимает reCAPTCHA сразу после рендеринга. Срок действия ответа reCAPTCHA истечет через некоторое время, а затем снова будет автоматически разрешен.
  • Невидимый reCAPTCHA : Невидимый reCAPTCHA не разрешается автоматически при рендеринге, а вместо этого делает это при вызове appVerifier.verify() или при нажатии привязки кнопки reCAPTCHA после задержки в доли секунды. Аналогично, срок действия ответа истечет через некоторое время и будет автоматически разрешен только после вызова appVerifier.verify() или при повторном нажатии привязки кнопки reCAPTCHA.

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

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

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

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

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

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

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

Web modular API

import { getAuth, signOut } from "firebase/auth";

const auth = getAuth();
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

Web namespaced API

firebase.auth().signOut().then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});