Save the date - Google I/O returns May 18-20. Register to get the most out of the digital experience: Build your schedule, reserve space, participate in Q&As, earn Google Developer profile badges, and more. Register now
Эта страница переведена с помощью Cloud Translation API.
Switch to English

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

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

Интернет v8

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

Интернет v9

import { getAuth } from "firebase/auth";

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

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

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

Интернет v8

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

Интернет v9

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

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

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

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

Интернет v8

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

Интернет v9

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

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

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

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

Интернет v8

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.
    // ...
  }
});

Интернет v9

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

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

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

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

Интернет v8

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

Интернет v9

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

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

Интернет v8

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Интернет v9

const recaptchaResponse = grecaptcha.getResponse(recaptchaWidgetId);

Отправьте проверочный код на телефон пользователя

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

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

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

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

    Интернет v8

    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
          // ...
        });

    Интернет v9

    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
          // ...
        });
    Если 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 вызова signInWithPhoneNumber предложите пользователю ввести проверочный код, полученный по SMS. Затем вход пользователя путем передачи коды в confirm способе ConfirmationResult объекта , который был передан в signInWithPhoneNumber исполнения обработчика «s (то есть, его then блок). Например:

Интернет v8

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?)
  // ...
});

Интернет v9

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 Authentication не позволяет вам устанавливать существующие телефонные номера, используемые реальными пользователями, в качестве тестовых. Один из вариантов - использовать 555 номеров с префиксом в качестве тестовых телефонных номеров в США, например: +1 650-555-3434.
  2. Номера телефонов должны быть правильно отформатированы с учетом длины и других ограничений. Они по-прежнему будут проходить ту же проверку, что и номер телефона реального пользователя.
  3. Вы можете добавить до 10 номеров телефонов для разработки.
  4. Используйте тестовые телефонные номера / коды, которые сложно угадать, и часто меняйте их.

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

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

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

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

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

По завершении входа создается пользователь Firebase с этим номером телефона. У пользователя такое же поведение и свойства, как у пользователя с реальным номером телефона, и он может получить доступ к базе данных Realtime / 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 объекта « User . См. Управление пользователями .

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

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

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

Интернет v8

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

Интернет v9

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

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