Расширенные функции аутентификации

1. Настройка

Получите исходный код

В этом практическом занятии вы начнете с почти готовой версии тестового приложения Friendly Chat, поэтому первое, что вам нужно сделать, это клонировать исходный код:

$ git clone https://github.com/firebase/codelab-friendlychat-web --branch security

Затем перейдите в каталог security-start , где вы будете работать до конца этого практического занятия:

$ cd codelab-friendlychat-web/security-start

Теперь установите зависимости, чтобы запустить код. Если у вас медленное интернет-соединение, это может занять минуту-две:

$ npm install && (cd functions && npm install)

Ознакомьтесь с этим репозиторием.

В каталоге security-solution/ находится полный код примера приложения. В каталоге security-start вы будете работать над практическим заданием, и в нем отсутствуют некоторые важные части реализации аутентификации. Ключевые файлы и функции в security-start/ и security-solution/ :

  • functions/index.js содержит код Cloud Functions, и именно здесь вы будете писать функции, блокирующие аутентификацию.
  • public/ — содержит статические файлы для вашего приложения чата.
  • public/scripts/main.js — файл, в который компилируется код JavaScript вашего чат-приложения ( src/index.js ).
  • src/firebase-config.js — содержит объект конфигурации Firebase, используемый для инициализации вашего приложения чата.
  • src/index.js - код JavaScript для вашего приложения чата

Получите Firebase CLI

Emulator Suite является частью Firebase CLI (интерфейса командной строки), который можно установить на ваш компьютер с помощью следующей команды:

$ npm install -g firebase-tools@latest

Соберите JavaScript с помощью webpack, в результате чего файл main.js будет создан в директории public/scripts/.

webpack build

Далее убедитесь, что у вас установлена ​​последняя версия CLI. Данный практический пример работает с версией 11.14 или выше.

$ firebase --version
11.14.2

Подключитесь к своему проекту Firebase.

Создайте новый проект Firebase.

  1. Войдите в консоль Firebase, используя свою учетную запись Google.
  2. Нажмите кнопку, чтобы создать новый проект, а затем введите название проекта (например, Authentication MFA Codelab ).
  3. Нажмите «Продолжить» .
  4. Если появится запрос, ознакомьтесь с условиями использования Firebase и примите их, после чего нажмите «Продолжить» .
  5. (Необязательно) Включите помощь ИИ в консоли Firebase (в Firebase она называется "Gemini").
  6. Для этого практического занятия вам не понадобится Google Analytics, поэтому отключите эту опцию.
  7. Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .

Подключите свой код к проекту Firebase.

Теперь вам нужно подключить этот код к вашему проекту Firebase. Сначала выполните следующую команду, чтобы войти в Firebase CLI:

$ firebase login

Далее выполните следующую команду, чтобы создать псевдоним проекта. Замените $YOUR_PROJECT_ID на идентификатор вашего проекта Firebase.

$ firebase use $YOUR_PROJECT_ID

Теперь вы готовы запустить приложение!

2. Запустите эмуляторы.

В этом разделе вы запустите приложение локально. Это значит, что пришло время запустить Emulator Suite.

Запустите эмуляторы

В каталоге с исходным кодом CodeLab выполните следующую команду для запуска эмуляторов:

$ firebase emulators:start

Это позволит запустить ваше приложение по адресу http://127.0.0.1:5170 и постоянно перестраивать исходный код по мере внесения изменений. Вам потребуется лишь принудительно обновить страницу (Ctrl-Shift-R) в браузере, чтобы увидеть изменения.

Вы должны увидеть примерно такой вывод:

i  emulators: Starting emulators: auth, functions, firestore, hosting, storage
✔  functions: Using node@16 from host.
i  firestore: Firestore Emulator logging to firestore-debug.log
✔  firestore: Firestore Emulator UI websocket is running on 9150.
i  hosting[demo-example]: Serving hosting files from: ./public
✔  hosting[demo-example]: Local server: http://127.0.0.1:5170
i  ui: Emulator UI logging to ui-debug.log
i  functions: Watching "[...]" for Cloud Functions...
✔  functions: Loaded functions definitions from source: beforecreated.
✔  functions[us-central1-beforecreated]: providers/cloud.auth/eventTypes/user.beforeCreate function initialized (http://127.0.0.1:5011/[...]/us-central1/beforecreated).
i  Running script: npm start
 
> security@1.0.0 start
> webpack --watch --progress
[...]
webpack 5.50.0 compiled with 1 warning in 990 ms

Как только вы увидите сообщение «Все эмуляторы готовы» , приложение будет готово к использованию.

3. Внедрение многофакторной аутентификации

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

В редакторе откройте файл src/index.js и найдите метод startEnrollMultiFactor() . Добавьте следующий код для настройки верификатора reCAPTCHA, который предотвратит злоупотребления телефонными звонками (верификатор reCAPTCHA будет невидим и не будет виден пользователям):

async function startEnrollMultiFactor(phoneNumber) {
  const recaptchaVerifier = new RecaptchaVerifier(
    "recaptcha",
    { size: "invisible" },
    getAuth()
  );

Затем найдите метод finishEnrollMultiFactor() и добавьте следующий код для регистрации второго фактора:

// Completes MFA enrollment once a verification code is obtained.
async function finishEnrollMultiFactor(verificationCode) {
  // Ask user for the verification code. Then:
  const cred = PhoneAuthProvider.credential(verificationId, verificationCode);
  const multiFactorAssertion = PhoneMultiFactorGenerator.assertion(cred);
 
  // Complete enrollment.
  await multiFactor(getAuth().currentUser)
    .enroll(multiFactorAssertion)
    .catch(function (error) {
      alert(`Error finishing second factor enrollment. ${error}`);
      throw error;
    });
  verificationId = null;
}

Далее найдите функцию signIn и добавьте следующий поток управления, который запрашивает у пользователей, зарегистрированных в системе многофакторной аутентификации (MFA), ввод второго фактора:

async function signIn() {
  // Sign in Firebase using popup auth and Google as the identity provider.
  var provider = new GoogleAuthProvider();
  await signInWithPopup(getAuth(), provider)
    .then(function (userCredential) {
      // User successfully signed in and is not enrolled with a second factor.
    })
    .catch(function (error) {
      if (error.code == "auth/multi-factor-auth-required") {
        multiFactorResolver = getMultiFactorResolver(getAuth(), error);
        displaySecondFactor(multiFactorResolver.hints);
      } else {
        alert(`Error signing in user. ${error}`);
      }
    });
}

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

4. Попробуйте войти в систему с помощью многофакторной аутентификации (MFA) в эмуляторах.

Теперь попробуйте реализовать многофакторную аутентификацию! Убедитесь, что ваши эмуляторы по-прежнему запущены, и зайдите в локальное приложение по адресу localhost:5170 . Попробуйте войти в систему, и когда вас попросят ввести код многофакторной аутентификации, вы увидите этот код в окне терминала.

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

Чтобы узнать больше о внедрении многофакторной аутентификации, ознакомьтесь с нашей справочной документацией .

5. Создайте блокирующую функцию.

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

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

Чтобы создать блокирующую функцию, откройте functions/index.js в редакторе и найдите закомментированную функцию beforecreated .

Замените его этим кодом, который позволит создавать учетные записи только пользователям с доменом example.com:

exports.beforecreated = beforeUserCreated((event) => {
  const user = event.data;
  // Only users of a specific domain can sign up.
  if (!user.email || !user.email.endsWith("@example.com")) {
    throw new HttpsError("invalid-argument", "Unauthorized email");
  }
});

6. Попробуйте функцию блокировки в эмуляторах.

Чтобы протестировать функцию блокировки, убедитесь, что ваши эмуляторы запущены, а в веб-приложении по адресу localhost:5170 выйдите из системы.

Затем попробуйте создать учетную запись с адресом электронной почты, который не заканчивается на example.com . Функция блокировки не позволит успешно выполнить эту операцию.

Теперь попробуйте еще раз, используя адрес электронной почты, заканчивающийся на example.com . Учетная запись будет успешно создана.

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

Краткий обзор

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

GIF-анимация, на которой сотрудники офиса исполняют танец "Raise the Roof".