Fonctionnalités d'authentification avancées

1. Configurer

Obtenir le code source

Dans cet atelier de programmation, vous commencez avec une version presque complète de l'application exemple Friendly Chat. La première chose que vous devez faire est donc de cloner le code source:

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

Accédez ensuite au répertoire security-start, dans lequel vous allez travailler pendant le reste de cet atelier de programmation:

$ cd codelab-friendlychat-web/security-start

Installez maintenant les dépendances pour pouvoir exécuter le code. Si votre connexion Internet est lente, cette opération peut prendre une à deux minutes:

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

Découvrir ce dépôt

Le répertoire security-solution/ contient le code complet de l'application exemple. Le répertoire security-start, dans lequel vous allez travailler dans l'atelier de programmation, ne contient pas quelques parties importantes de l'implémentation de l'authentification. Voici les principaux fichiers et fonctionnalités de security-start/ et security-solution/:

  • functions/index.js contient du code Cloud Functions. C'est là que vous allez écrire des fonctions de blocage de l'authentification.
  • public/ : contient les fichiers statiques de votre application de chat
  • public/scripts/main.js : emplacement où le code JavaScript de votre application de chat (src/index.js) est compilé
  • src/firebase-config.js : contient l'objet de configuration Firebase utilisé pour initialiser votre application de chat
  • src/index.js : code JavaScript de votre application de chat

Obtenir la CLI Firebase

La suite d'émulateurs fait partie de la CLI Firebase (interface de ligne de commande), que vous pouvez installer sur votre ordinateur à l'aide de la commande suivante:

$ npm install -g firebase-tools@latest

Créez le code JavaScript avec webpack, qui créera main.js dans le répertoire public/scripts/.

webpack build

Vérifiez ensuite que vous disposez de la dernière version de la CLI. Cet atelier de programmation fonctionne avec la version 11.14 ou ultérieure.

$ firebase --version
11.14.2

Associer votre projet Firebase

Si vous ne possédez pas de projet Firebase, créez-en un dans la console Firebase. Notez l'ID de projet que vous choisissez, car vous en aurez besoin plus tard.

Vous devez maintenant associer ce code à votre projet Firebase. Commencez par exécuter la commande suivante pour vous connecter à la CLI Firebase:

$ firebase login

Exécutez ensuite la commande suivante pour créer un alias de projet. Remplacez $YOUR_PROJECT_ID par l'ID de votre projet Firebase.

$ firebase use $YOUR_PROJECT_ID

Vous êtes maintenant prêt à exécuter l'application.

2. Exécuter les émulateurs

Dans cette section, vous allez exécuter l'application en local. Il est donc temps de démarrer la suite d'émulateurs.

Démarrer les émulateurs

Dans le répertoire source du tutoriel, exécutez la commande suivante pour démarrer les émulateurs:

$ firebase emulators:start

Votre application sera diffusée à l'adresse http://127.0.0.1:5170 et votre code source sera reconstruit en continu à mesure que vous apporterez des modifications. Pour voir les modifications, il vous suffit d'effectuer une actualisation forcée (Ctrl+Maj+R) localement dans votre navigateur.

Le résultat devrait ressembler à ceci:

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

Lorsque le message Tous les émulateurs sont prêts s'affiche, l'application est prête à l'emploi.

3. Implémenter l'authentification multifacteur

L'authentification multifacteur a été partiellement implémentée dans ce dépôt. Vous allez ajouter le code pour enregistrer d'abord un utilisateur dans l'authentification multifacteur, puis pour inviter les utilisateurs inscrits à l'authentification multifacteur à fournir un deuxième facteur.

Dans votre éditeur, ouvrez le fichier src/index.js et recherchez la méthode startEnrollMultiFactor(). Ajoutez le code suivant pour configurer l'outil de vérification reCAPTCHA qui empêchera l'utilisation abusive du téléphone (l'outil de vérification reCAPTCHA est défini sur "invisible" et ne sera pas visible par les utilisateurs):

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

Recherchez ensuite la méthode finishEnrollMultiFactor() et ajoutez ce qui suit pour enregistrer le deuxième facteur:

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

Recherchez ensuite la fonction signIn et ajoutez le flux de contrôle suivant, qui invite les utilisateurs inscrits au MFA à saisir leur deuxième facteur:

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}`);
      }
    });
}

Le reste de l'implémentation, y compris les fonctions appelées ici, est déjà terminé. Pour voir comment ils fonctionnent, parcourez le reste du fichier.

4. Essayer de vous connecter avec l'authentification multifacteur dans les émulateurs

Essayez maintenant l'implémentation de l'authentification multifacteur. Assurez-vous que vos émulateurs sont toujours en cours d'exécution et accédez à l'application hébergée localement sur localhost:5170. Essayez de vous connecter. Lorsque vous êtes invité à fournir le code d'authentification multifacteur, il s'affiche dans la fenêtre du terminal.

Étant donné que les émulateurs sont entièrement compatibles avec l'authentification multifacteur, votre environnement de développement peut être entièrement autonome.

Pour en savoir plus sur l'implémentation de l'authentification multifacteur, consultez nos documents de référence.

5. Créer une fonction de blocage

Certaines applications ne sont destinées qu'à un groupe d'utilisateurs spécifique. Dans ce cas, vous devez pouvoir créer des exigences personnalisées pour qu'un utilisateur puisse s'inscrire ou se connecter à votre application.

C'est ce que les fonctions de blocage vous permettent de faire: créer des exigences d'authentification personnalisées. Il s'agit de fonctions Cloud, mais contrairement à la plupart des fonctions, elles s'exécutent de manière synchrone lorsqu'un utilisateur tente de s'inscrire ou de se connecter.

Pour créer une fonction bloquante, ouvrez functions/index.js dans votre éditeur et recherchez la fonction beforecreated commentée.

Remplacez-la par le code suivant, qui n'autorise que les utilisateurs disposant d'un domaine example.com à créer un compte:

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. Tester la fonction de blocage dans les émulateurs

Pour tester la fonction de blocage, assurez-vous que vos émulateurs sont en cours d'exécution et déconnectez-vous de l'application Web à l'adresse localhost:5170.

Essayez ensuite de créer un compte avec une adresse e-mail qui ne se termine pas par example.com. La fonction de blocage empêche l'opération de réussir.

Réessayez avec une adresse e-mail se terminant par example.com. Le compte sera créé.

Les fonctions de blocage vous permettent de créer toutes les restrictions d'authentification dont vous avez besoin. Pour en savoir plus, consultez la documentation de référence.

Résumé

Bravo ! Vous avez ajouté l'authentification multifacteur à une application Web pour aider les utilisateurs à sécuriser leur compte, puis vous avez créé des exigences personnalisées pour que les utilisateurs puissent s'inscrire à l'aide de fonctions de blocage. Vous méritez vraiment un GIF !

un GIF de personnes du bureau faisant la danse "Raise the roof"