1. Configurar
Obtén el código fuente
En este codelab, comenzarás con una versión casi completa de la app de ejemplo de Friendly Chat, por lo que lo primero que debes hacer es clonar el código fuente:
$ git clone https://github.com/firebase/codelab-friendlychat-web --branch security
Luego, ve al directorio security-start
, donde trabajarás durante el resto de este codelab:
$ cd codelab-friendlychat-web/security-start
Ahora, instala las dependencias para poder ejecutar el código. Si tienes una conexión a Internet más lenta, esto puede tardar uno o dos minutos:
$ npm install && (cd functions && npm install)
Conoce este repo
El directorio security-solution/
contiene el código completo de la app de ejemplo. El directorio security-start
es donde trabajarás en el codelab y le faltan algunas partes importantes de la implementación de la autenticación. Los archivos y las funciones clave en security-start/
y security-solution/
son los siguientes:
functions/index.js
contiene el código de Cloud Functions y es donde escribirás las funciones de bloqueo de autorización.public/
: Contiene los archivos estáticos de tu app de chatpublic/scripts/main.js
: Es donde se compila el código JS de tu app de chat (src/index.js
).src/firebase-config.js
: Contiene el objeto de configuración de Firebase que se usa para inicializar tu app de chat.src/index.js
: Es el código JS de tu app de chat.
Obtén Firebase CLI
Emulator Suite forma parte de Firebase CLI (interfaz de línea de comandos), que se puede instalar en tu máquina con el siguiente comando:
$ npm install -g firebase-tools@latest
Compila el código JavaScript con webpack, lo que creará main.js dentro del directorio public/scripts/.
webpack build
A continuación, confirma que tienes la versión más reciente de la CLI. Este codelab funciona con la versión 11.14 o posterior.
$ firebase --version 11.14.2
Conéctate a tu proyecto de Firebase
Si no tienes un proyecto de Firebase, crea uno nuevo en Firebase console. Toma nota del ID del proyecto que elijas, ya que lo necesitarás más adelante.
Ahora debes conectar este código a tu proyecto de Firebase. Primero, ejecuta el siguiente comando para acceder a Firebase CLI:
$ firebase login
A continuación, ejecuta el siguiente comando para crear un alias del proyecto. Reemplaza $YOUR_PROJECT_ID
por el ID de tu proyecto de Firebase.
$ firebase use $YOUR_PROJECT_ID
Ya puedes ejecutar la app.
2. Ejecuta los emuladores
En esta sección, ejecutarás la app de manera local. Esto significa que es hora de iniciar Emulator Suite.
Inicia los emuladores
Desde el directorio fuente del codelab, ejecuta el siguiente comando para iniciar los emuladores:
$ firebase emulators:start
Esto publicará tu app en http://127.0.0.1:5170 y volverá a compilar tu código fuente de forma continua a medida que realices cambios. Solo deberás realizar una actualización forzada (Ctrl + Mayúsculas + R) de forma local en tu navegador para ver los cambios.
Deberías ver un resultado similar al siguiente:
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
Cuando veas el mensaje All emulators ready, la app estará lista para usarse.
3. Implementa la MFA
La MFA se implementó parcialmente en este repo. Agregarás el código para inscribir primero a un usuario en la MFA y, luego, para solicitarles a los usuarios inscritos en la MFA un segundo factor.
En el editor, abre el archivo src/index.js
y busca el método startEnrollMultiFactor()
. Agrega el siguiente código para configurar el verificador de reCAPTCHA que evitará el abuso telefónico (el verificador de reCAPTCHA se configura como invisible y no será visible para los usuarios):
async function startEnrollMultiFactor(phoneNumber) {
const recaptchaVerifier = new RecaptchaVerifier(
"recaptcha",
{ size: "invisible" },
getAuth()
);
Luego, busca el método finishEnrollMultiFactor()
y agrega lo siguiente para inscribir el segundo factor:
// 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;
}
A continuación, busca la función signIn
y agrega el siguiente flujo de control que les solicita a los usuarios inscritos en la MFA que ingresen su segundo factor:
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}`);
}
});
}
El resto de la implementación, incluidas las funciones que se invocan aquí, ya está completo. Para ver cómo funcionan, explora el resto del archivo.
4. Prueba el acceso con MFA en los emuladores
Ahora prueba la implementación de la MFA. Asegúrate de que los emuladores sigan en ejecución y visita la app alojada de forma local en localhost:5170
. Intenta acceder y, cuando se te solicite que proporciones el código de MFA, lo verás en la ventana de la terminal.
Dado que los emuladores admiten completamente la autenticación de varios factores, tu entorno de desarrollo puede ser completamente autónomo.
Para obtener más información sobre la implementación de la MFA, consulta nuestros documentos de referencia.
5. Crea una función de bloqueo
Algunas aplicaciones están diseñadas para ser usadas solo por un grupo específico de usuarios. En esos casos, querrás poder crear requisitos personalizados para que un usuario se registre o acceda a tu app.
Eso es lo que proporcionan las funciones de bloqueo: una forma de crear requisitos de autenticación personalizados. Son Cloud Functions, pero, a diferencia de la mayoría de las funciones, se ejecutan de forma síncrona cuando un usuario intenta registrarse o acceder.
Para crear una función de bloqueo, abre functions/index.js
en tu editor y busca la función beforecreated
comentada.
Reemplázalo por este código que solo permite que los usuarios con un dominio de example.com creen una cuenta:
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. Prueba la función de bloqueo en los emuladores
Para probar la función de bloqueo, asegúrate de que los emuladores estén en ejecución y, en la app web en localhost:5170
, cierra la sesión.
Luego, intenta crear una cuenta con una dirección de correo electrónico que no termine en example.com
. La función de bloqueo evitará que la operación se realice correctamente.
Ahora, vuelve a intentarlo con una dirección de correo electrónico que sí termine en example.com
. La cuenta se creará correctamente.
Con las funciones de bloqueo, puedes crear las restricciones que necesites en torno a la autenticación. Para obtener más información, consulta los documentos de referencia.
Resumen
¡Bien hecho! Agregaste la autenticación de varios factores a una app web para ayudar a los usuarios a mantener segura su cuenta y, luego, creaste requisitos personalizados para que los usuarios se registren con funciones de bloqueo. ¡Sin duda te mereces un GIF!