Ir a la consola

Autentica con Firebase mediante un número de teléfono con JavaScript

Puedes usar Firebase Authentication para hacer que un usuario acceda mediante el envío de un mensaje SMS a su teléfono. El usuario accede con un código único que se incluye en el mensaje SMS.

La forma más fácil de agregar un acceso con número de teléfono a la app es usar FirebaseUI, que incluye un widget de acceso directo que implementa flujos de acceso con número de teléfono, además de acceso federado y con contraseña. En este documento, se describe cómo implementar un flujo de acceso con el número de teléfono mediante el uso del SDK de Firebase.

Antes de comenzar

Si aún no lo has hecho, copia el fragmento de inicialización de Firebase console en el proyecto, como se describe en Agrega Firebase a tu proyecto de JavaScript.

Preocupaciones de seguridad

Si bien la autenticación con solo un número de teléfono es conveniente, es menos segura que otros métodos disponibles, ya que la posesión de un número de teléfono se puede transferir con facilidad entre usuarios. Además, en los dispositivos con varios perfiles de usuario, cualquier usuario que reciba mensajes SMS puede acceder a una cuenta con el número de teléfono del dispositivo.

Si usas el acceso con número de teléfono en la app, deberías ofrecerlo junto con métodos de acceso más seguros, además de informar a los usuarios acerca de las desventajas de usar el acceso con número de teléfono.

Habilita el acceso con número de teléfono para el proyecto de Firebase

Para que los usuarios accedan a través de SMS, primero debes habilitar el método de acceso con el número de teléfono para el proyecto de Firebase:

  1. En Firebase console, abre la sección Authentication.
  2. En la página Método de acceso, habilita el método de acceso Número de teléfono.
  3. En la misma página, si el dominio que alojará la app no aparece en la lista de la sección dominios de redirección de OAuth, agrega tu dominio.

La cuota de solicitudes de acceso con el número de teléfono de Firebase es lo suficientemente alta para que la mayoría de las apps no tengan problemas. Sin embargo, si necesitas permitir el acceso de un gran volumen de usuarios con autenticación por teléfono, es posible que debas actualizar tu plan de precios. Consulta la página de precios.

Configura el verificador reCAPTCHA

Para poder habilitar el acceso de los usuarios con sus números de teléfono, debes configurar el verificador reCAPTCHA de Firebase. Firebase usa reCAPTCHA para evitar abusos. Por ejemplo, se asegura de que la solicitud de verificación del número de teléfono provenga de uno de los dominios permitidos de la app.

No es necesario que configures un cliente reCAPTCHA de forma manual; cuando usas el objeto RecaptchaVerifier del SDK de Firebase, Firebase crea y maneja de forma automática todos los secretos y las claves necesarios del cliente.

El objeto RecaptchaVerifier admite reCAPTCHA invisible, que a menudo puede verificar al usuario sin necesidad de que este ejecute una acción, además del widget reCAPTCHA, que siempre solicita la interacción del usuario para completarse de forma correcta.

El reCAPTCHA subyacente que se muestra puede localizarse según la preferencia del usuario mediante la actualización del código de idioma en la instancia de Auth antes de procesar el reCAPTCHA. La localización mencionada también se aplicará al mensaje SMS que se envía al usuario y que contiene el código de verificación.

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

Usa un reCAPTCHA invisible

Para usar un reCAPTCHA invisible, crea un objeto RecaptchaVerifier, asigna al parámetro size el valor invisible y especifica el ID del botón que envía tu formulario de acceso. Por ejemplo:

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

Usa el widget reCAPTCHA

Para usar el widget reCAPTCHA visible, crea un elemento en tu página para que contenga el widget y, luego, crea un objeto RecaptchaVerifier y especifica el ID del contenedor cuando lo hagas. Por ejemplo:

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

Opcional: Especifica los parámetros de reCAPTCHA

De forma opcional, puedes configurar funciones de devolución de llamada en el objeto RecaptchaVerifier a las que se envían llamadas cuando el usuario resuelve el reCAPTCHA o el reCAPTCHA vence antes de que el usuario envíe el formulario:

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

Opcional: Procesa por adelantado el reCAPTCHA

Si deseas procesar por adelantado el reCAPTCHA antes de enviar una solicitud de acceso, llama a render:

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

Cuando render se resuelve, obtienes el ID del widget reCAPTCHA, que puedes usar para hacer llamadas a la API de reCAPTCHA de la siguiente manera:

var recaptchaResponse = grecaptcha.getResponse(window.recaptchaWidgetId);

Envía un código de verificación al teléfono del usuario

Para iniciar el acceso con el número de teléfono, muéstrale al usuario una interfaz que le pida ingresar su número de teléfono y, luego, llama a signInWithPhoneNumber para solicitar a Firebase que envíe un código de autenticación al teléfono del usuario mediante SMS:

  1. Obtén el número de teléfono del usuario.

    Los requisitos legales varían, pero es recomendable establecer las expectativas de los usuarios informándoles que, si usan el acceso con el teléfono, es posible que reciban un mensaje SMS para la verificación y que se aplicarán las tarifas estándar.

  2. Llama a signInWithPhoneNumber con el número de teléfono del usuario y el RecaptchaVerifier que creaste antes como sus parámetros.
    var phoneNumber = getPhoneNumberFromUserInput();
    var appVerifier = window.recaptchaVerifier;
    firebase.auth().signInWithPhoneNumber(phoneNumber, appVerifier)
        .then(function (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(function (error) {
          // Error; SMS not sent
          // ...
        });
    Si signInWithPhoneNumber da como resultado un error, reinicia el reCAPTCHA para que el usuario pueda volver a intentarlo:
    grecaptcha.reset(window.recaptchaWidgetId);
    
    // Or, if you haven't stored the widget ID:
    window.recaptchaVerifier.render().then(function(widgetId) {
      grecaptcha.reset(widgetId);
    }
    

El método signInWithPhoneNumber envía el desafío reCAPTCHA al usuario y, si el usuario lo pasa, solicita que Firebase Authentication envíe al teléfono del usuario un mensaje SMS que contiene un código de verificación.

Permite el acceso del usuario con el código de verificación

Después de ejecutar correctamente la llamada a signInWithPhoneNumber, pide al usuario que ingrese el código de verificación que recibió por SMS. Luego, para hacer que el usuario acceda, pasa el código al método confirm del objeto ConfirmationResult que se pasó al controlador de cumplimiento de signInWithPhoneNumber (es decir, su bloque then). Por ejemplo:

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

Si la llamada a confirm se ejecuta como corresponde, el usuario accederá de forma correcta.

Obtén el objeto intermedio AuthCredential

Si necesitas obtener un objeto AuthCredential para la cuenta del usuario, pasa el código de verificación del resultado de la confirmación y el código de verificación a PhoneAuthProvider.credential en lugar de llamar a confirm:

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

Luego, puedes habilitar el acceso del usuario con la credencial:

firebase.auth().signInAndRetrieveDataWithCredential(credential);

Prueba con números de teléfono incluidos en la lista blanca

Puedes incluir números de teléfono para desarrollo en la lista blanca a través de Firebase console. Una lista blanca de números de teléfono ofrece los siguientes beneficios:

  • Prueba la autenticación del número de teléfono sin consumir tu cuota de uso.
  • Prueba la autenticación del número de teléfono sin enviar un mensaje SMS real.
  • Ejecuta pruebas consecutivas con el mismo número de teléfono sin regulación. Esto minimiza el riesgo de rechazo durante el proceso de revisión de la tienda de aplicaciones si el revisor utiliza el mismo número de teléfono para las pruebas.
  • Realiza pruebas con facilidad en entornos de desarrollo sin ningún esfuerzo adicional, por ejemplo, obtén la capacidad de desarrollar en un simulador de iOS o un emulador de Android sin los Servicios de Google Play.
  • Escribe pruebas de integración sin ser bloqueado por los controles de seguridad que normalmente se aplican a los números de teléfono reales en un entorno de producción.

Para incluir números de teléfono en la lista blanca, es necesario cumplir estos requisitos:

  1. Asegúrate de usar números ficticios que aún no existan. Firebase Authentication no permite incluir en la lista blanca números de teléfono existentes, que tengan usuarios reales. Una opción es usar números con el prefijo 555 como números de teléfono de prueba de EE.UU., por ejemplo: +1 650-555-3434.
  2. Los números de teléfono deben tener el formato adecuado de longitud y otras restricciones. Estos números pasarán por la misma validación que el número de teléfono de un usuario real.
  3. Puedes agregar hasta 10 números de teléfono.
  4. Usa códigos o números de teléfono de prueba que sean difíciles de adivinar y cámbialos con frecuencia.

Incluye números de teléfono y códigos de verificación en la lista blanca

  1. En Firebase console, abre la sección Authentication.
  2. En la pestaña Método de acceso, habilita el proveedor de telefonía, si todavía no lo has hecho.
  3. Abre el menú de acordeón Números de teléfono para la prueba.
  4. Proporciona el número de teléfono que deseas probar, por ejemplo: +1 650-555-3434.
  5. Proporciona el código de verificación de 6 dígitos para ese número específico, por ejemplo: 654321.
  6. Agrega el número. Si es necesario, puedes desplazarte sobre la fila correspondiente y hacer clic en el ícono de papelera para borrar el número de teléfono y su código.

Pruebas manuales

En tu aplicación, puedes comenzar a usar directamente un número de teléfono incluido en la lista blanca. Esto te permite realizar pruebas manuales durante las etapas de desarrollo sin que te encuentres con problemas de cuota o regulación. También puedes realizar pruebas directamente desde un simulador de iOS o un emulador de Android sin tener los Servicios de Google Play instalados.

Cuando se proporciona el número de teléfono incluido en la lista blanca y se envía el código de verificación, no se envía ningún SMS real. En lugar de eso, es necesario proporcionar el código de verificación previamente configurado para completar el acceso.

Cuando se completa el acceso, se crea un usuario de Firebase con ese número de teléfono. El usuario tiene el mismo comportamiento y las mismas propiedades que el usuario de un número de teléfono real, y puede acceder de la misma manera a Realtime Database, Cloud Firestore y otros servicios. El token de ID emitido durante este proceso tiene la misma firma que el usuario de un número de teléfono real.

Otra opción es configurar una función de prueba mediante reclamaciones personalizadas en estos usuarios para diferenciarlos como usuarios falsos si se desea restringir más el acceso.

Pruebas de integración

Además de las pruebas manuales, Firebase Authentication proporciona las API con las que es posible escribir pruebas de integración para la autenticación del teléfono. Para inhabilitar la verificación de app, estas API inhabilitan el requisito reCAPTCHA en las notificaciones push silenciosas y web en iOS. Esto permite que se realicen las pruebas de automatización en estos flujos y facilita su implementación. Además, las API proporcionan la capacidad de probar flujos de verificación instantánea en Android.

En la Web, configura appVerificationDisabledForTesting como true antes de procesar el firebase.auth.RecaptchaVerifier. Esto resuelve el reCAPTCHA automáticamente, lo que te permite pasar el número de teléfono sin tener que resolverlo de manera manual. Ten en cuenta que incluso si el reCAPTCHA está inhabilitado, el uso de un número de teléfono que no esté en la lista blanca no completará el acceso. Solo se pueden usar números de teléfono incluidos en la lista blanca con esta 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 whitelisted testVerificationCode above.
      return confirmationResult.confirm(testVerificationCode)
    }).catch(function (error) {
      // Error; SMS not sent
      // ...
    });

Los verificadores de app del reCAPTCHA invisible y visible de prueba se comportan de manera diferente cuando la verificación de la app está inhabilitada:

  • reCAPTCHA visible: cuando el reCAPTCHA visible se procesa a través de appVerifier.render(), se resuelve automáticamente después de una fracción de segundo. Esto equivale a que el usuario haga clic en el reCAPTCHA inmediatamente cuando se procesa. La respuesta de reCAPTCHA vencerá después de un tiempo, pero se resolverá nuevamente de manera automática.
  • reCAPTCHA invisible: el reCAPTCHA invisible no se resuelve automáticamente durante el procesamiento, sino cuando se produce la llamada a appVerifier.verify() o bien cuando se hace clic en el anclaje del botón de reCAPTCHA después de una fracción de segundo. Asimismo, la respuesta vencerá después de un tiempo y solo se resolverá automáticamente tras una llamada a appVerifier.verify() o cuando se haya hecho clic nuevamente en el anclaje del botón de reCAPTCHA.

La función de devolución de llamada correspondiente se activa con la respuesta falsa, tal como se esperaba, cada vez que se resuelve un reCAPTCHA de prueba. Si también se especifica la devolución de llamada de un vencimiento, se activará con el vencimiento.

Próximos pasos

Cuando un usuario accede por primera vez, se crea una cuenta de usuario nueva y se la vincula con las credenciales (el nombre de usuario y la contraseña, el número de teléfono o la información del proveedor de autenticación) con las que accedió el usuario. Esta cuenta nueva se almacena como parte del proyecto de Firebase y puede usarse para identificar a un usuario en todas las apps del proyecto, sin importar el método de acceso que se use.

  • En las apps, para conocer el estado de autenticación del usuario, te recomendamos configurar un observador en el objeto Auth. Puedes obtener la información básica de perfil del usuario a partir del objeto User. Consulta Cómo administrar usuarios.

  • En las reglas de seguridad de Firebase Realtime Database y Cloud Storage, puedes obtener el ID único del usuario que accedió a partir de la variable auth y usarlo para controlar los datos a los que tiene acceso.

Para permitir que los usuarios accedan a tu app con varios proveedores de autenticación, puedes vincular las credenciales de proveedores de autenticación con una cuenta de usuario existente.

Para salir de la sesión de un usuario, llama a signOut de la siguiente manera:

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