Autenticarse con Firebase usando un número de teléfono y C++

Puede utilizar Firebase Authentication para iniciar sesión en un usuario enviando un mensaje SMS al teléfono del usuario. El usuario inicia sesión utilizando un código de un solo uso contenido en el mensaje SMS.

Este documento describe cómo implementar un flujo de inicio de sesión con un número de teléfono mediante el SDK de Firebase.

Antes de que empieces

  1. Agrega Firebase a tu proyecto de C++ .
  2. Si aún no has conectado tu aplicación a tu proyecto de Firebase, hazlo desde Firebase console .
  3. Comprenda los requisitos de la plataforma para iniciar sesión con el número de teléfono:
    • El inicio de sesión con número de teléfono es solo para plataformas móviles.
    • En iOS, el inicio de sesión con número de teléfono requiere un dispositivo físico y no funciona en un simulador.

Preocupaciones de seguridad

La autenticación utilizando sólo un número de teléfono, si bien es conveniente, es menos segura que otros métodos disponibles, porque la posesión de un número de teléfono puede transferirse fácilmente entre usuarios. Además, en dispositivos con múltiples perfiles de usuario, cualquier usuario que pueda recibir mensajes SMS puede iniciar sesión en una cuenta utilizando el número de teléfono del dispositivo.

Si utiliza el inicio de sesión basado en un número de teléfono en su aplicación, debe ofrecerlo junto con métodos de inicio de sesión más seguros e informar a los usuarios sobre las ventajas y desventajas de seguridad que implica el uso del inicio de sesión por número de teléfono.

Habilite el inicio de sesión con número de teléfono para su proyecto de Firebase

Para iniciar sesión de usuarios mediante SMS, primero debes habilitar el método de inicio de sesión con número de teléfono para tu proyecto de Firebase:

  1. En Firebase console , abre la sección Autenticación .
  2. En la página Método de inicio de sesión , habilite el método de inicio de sesión por número de teléfono .

La cuota de solicitudes de inicio de sesión de números de teléfono de Firebase es lo suficientemente alta como para que la mayoría de las aplicaciones no se vean afectadas. Sin embargo, si necesita iniciar sesión en un volumen muy grande de usuarios con autenticación telefónica, es posible que deba actualizar su plan de precios. Vea la página de precios .

Comience a recibir notificaciones de APN (plataformas Apple)

Para utilizar la autenticación de número de teléfono en las plataformas Apple, su aplicación debe poder recibir notificaciones de APN de Firebase. Cuando inicias sesión de un usuario con su número de teléfono por primera vez en un dispositivo, Firebase Authentication envía una notificación push silenciosa al dispositivo para verificar que la solicitud de inicio de sesión del número de teléfono proviene de tu aplicación. (Por este motivo, el inicio de sesión con número de teléfono no se puede utilizar en un simulador).

Para habilitar las notificaciones de APN para usar con Firebase Authentication:

  1. En Xcode, habilite las notificaciones push para su proyecto.
  2. Cargue su certificado APN en Firebase. Si aún no tiene un certificado APN, asegúrese de crear uno en el Centro de miembros desarrolladores de Apple .

    1. Dentro de su proyecto en Firebase console, seleccione el ícono de ajustes, seleccione Configuración del proyecto y luego seleccione la pestaña Mensajería en la nube .

    2. Seleccione el botón Cargar certificado para su certificado de desarrollo, su certificado de producción o ambos. Se requiere al menos uno.

    3. Para cada certificado, seleccione el archivo .p12 y proporcione la contraseña, si corresponde. Asegúrese de que el ID del paquete de este certificado coincida con el ID del paquete de su aplicación. Seleccione Guardar .

Enviar un código de verificación al teléfono del usuario

Para iniciar el inicio de sesión con el número de teléfono, presente al usuario una interfaz que le solicite que proporcione su número de teléfono y luego llame a PhoneAuthProvider::VerifyPhoneNumber para solicitar que Firebase envíe un código de autenticación al teléfono del usuario por SMS:

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

    Los requisitos legales varían, pero como práctica recomendada y para establecer expectativas para sus usuarios, debe informarles que si utilizan el inicio de sesión por teléfono, es posible que reciban un mensaje SMS para verificación y se aplicarán tarifas estándar.

  2. Llame a PhoneAuthProvider::VerifyPhoneNumber , pasándole el número de teléfono del usuario.
    class PhoneListener : public PhoneAuthProvider::Listener {
     public:
      ~PhoneListener() override {}
    
      void OnVerificationCompleted(PhoneAuthCredential credential) override {
        // Auto-sms-retrieval or instant validation has succeeded (Android only).
        // No need for the user to input the verification code manually.
        // `credential` can be used instead of calling GetCredential().
      }
    
      void OnVerificationFailed(const std::string& error) override {
        // Verification code not sent.
      }
    
      void OnCodeSent(const std::string& verification_id,
                      const PhoneAuthProvider::ForceResendingToken&
                          force_resending_token) override {
        // Verification code successfully sent via SMS.
        // Show the Screen to enter the Code.
        // Developer may want to save that verification_id along with other app states in case
        // the app is terminated before the user gets the SMS verification code.
      }
    };
    
    PhoneListener phone_listener;
    PhoneAuhtOptions options;
    options.timeout_milliseconds = kAutoVerifyTimeOut;
    options.phone_number = phone_number;
    PhoneAuthProvider& phone_provider = PhoneAuthProvider::GetInstance(auth);
    phone_provider->VerifyPhoneNumber(options, &phone_listener);
    
    Cuando llamas PhoneAuthProvider::VerifyPhoneNumber , Firebase,
    • (en iOS) envía una notificación push silenciosa a su aplicación,
    • envía un mensaje SMS que contiene un código de autenticación al número de teléfono especificado y pasa una identificación de verificación a su función de finalización. Necesitará tanto el código de verificación como el ID de verificación para iniciar sesión como usuario.
  3. Guarde la ID de verificación y restáurela cuando se cargue su aplicación. Al hacerlo, puede asegurarse de tener una identificación de verificación válida si su aplicación finaliza antes de que el usuario complete el flujo de inicio de sesión (por ejemplo, al cambiar a la aplicación de SMS).

    Puede conservar el ID de verificación de la forma que desee. Si está escribiendo con un marco C++ multiplataforma, debería proporcionar notificaciones para la finalización y restauración de la aplicación. En estos eventos, puede guardar y restaurar, respectivamente, la identificación de verificación.

Si la llamada a VerifyPhoneNumber da como resultado que se llame OnCodeSent en su oyente, puede pedirle al usuario que escriba el código de verificación cuando lo reciba en el mensaje SMS.

Por otro lado, si la llamada a VerifyPhoneNumber da como resultado OnVerificationCompleted , entonces la verificación automática se realizó correctamente y ahora tendrá una PhoneAuthCredential con la que podrá usar como se describe a continuación.

Inicia sesión como usuario con el código de verificación.

Después de que el usuario proporcione a su aplicación el código de verificación del mensaje SMS, inicie sesión creando un objeto PhoneAuthCredential a partir del código de verificación y el ID de verificación y pasando ese objeto a Auth::SignInWithCredential .

  1. Obtenga el código de verificación del usuario.
  2. Cree un objeto Credential a partir del código de verificación y el ID de verificación.
    PhoneAuthCredential credential = phone_auth_provider->GetCredential(
        verification_id_.c_str(), verification_code.c_str());
        
  3. Inicie sesión como usuario con el objeto Credential :
    Future<User> future = auth_->SignInWithCredential(credential);
    future.OnCompletion(
        [](const Future<User*>& result, void*) {
          if (result.error() == kAuthErrorNone) {
            // Successful.
            // User is signed in.
            User user = *result.result();
    
            // This should display the phone number.
            printf("Phone number: %s", user.phone_number().c_str());
    
            // The phone number provider UID is the phone number itself.
            printf("Phone provider uid: %s", user.uid().c_str());
    
            // The phone number providerID is 'phone'
            printf("Phone provider ID: %s", user.provider_id().c_str());
          } else {
            // Error.
            printf("Sign in error: %s", result.error_message().c_str());
          }
        },
        nullptr);
    

Próximos pasos

Después de que un usuario inicia sesión por primera vez, se crea una nueva cuenta de usuario y se vincula a las credenciales (es decir, 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 el usuario inició sesión. Esta nueva cuenta se almacena como parte de su proyecto de Firebase y se puede usar para identificar a un usuario en cada aplicación de su proyecto, independientemente de cómo inicie sesión el usuario.

  • En sus aplicaciones, puede obtener la información básica del perfil del usuario desde firebase::auth::User objeto:

    firebase::auth::User user = auth->current_user();
    if (user.is_valid()) {
      std::string name = user.display_name();
      std::string email = user.email();
      std::string photo_url = user.photo_url();
      // The user's ID, unique to the Firebase project.
      // Do NOT use this value to authenticate with your backend server,
      // if you have one. Use firebase::auth::User::Token() instead.
      std::string uid = user.uid();
    }
    
  • En las reglas de seguridad de Firebase Realtime Database y Cloud Storage, puede obtener el ID de usuario único del usuario que inició sesión a partir de la variable auth y usarlo para controlar a qué datos puede acceder un usuario.

Puede permitir que los usuarios inicien sesión en su aplicación utilizando múltiples proveedores de autenticación vinculando las credenciales del proveedor de autenticación a una cuenta de usuario existente.

Para cerrar la sesión de un usuario, llame a SignOut() :

auth->SignOut();