Autenticar usuarios con Firebase

ID de región

El REGION_ID es un código abreviado que Google asigna en función de la región que selecciones al crear tu aplicación. El código no corresponde a un país o provincia, aunque algunos IDs de región pueden parecerse a los códigos de país y provincia que se usan habitualmente. En las aplicaciones creadas después de febrero del 2020, REGION_ID.r se incluye en las URLs de App Engine. En las aplicaciones creadas antes de esa fecha, el ID de región es opcional en la URL.

Más información sobre los IDs de región

Añade un flujo de inicio de sesión de usuario a tu servicio web que use Firebase Authentication.

En este paso de la guía, actualizarás tu servicio web para autenticar a los usuarios y para recuperar y mostrar la información de un usuario después de que se autentique. Ten en cuenta que, en este paso, los tiempos de solicitud del sitio seguirán siendo globales en lugar de específicos de cada usuario.

Antes de empezar

Si has completado todos los pasos anteriores de esta guía, puedes saltarte esta sección. De lo contrario, realice una de las siguientes acciones:

Añadir métodos de autenticación de Firebase

Firebase proporciona métodos y variables de JavaScript que puedes usar para configurar el comportamiento de inicio de sesión de tu servicio web. En este servicio web, añade una función de cierre de sesión, una variable que configure la interfaz de usuario de inicio de sesión y una función que controle los cambios que se producen cuando un usuario inicia o cierra sesión.

Para añadir los comportamientos necesarios para un flujo de autenticación, sustituye el método de escucha de eventos actual del archivo static/script.js por el siguiente código:

window.addEventListener('load', function () {
  document.getElementById('sign-out').onclick = function () {
    firebase.auth().signOut();
  };

  // FirebaseUI config.
  var uiConfig = {
    signInSuccessUrl: '/',
    signInOptions: [
      // Comment out any lines corresponding to providers you did not check in
      // the Firebase console.
      firebase.auth.GoogleAuthProvider.PROVIDER_ID,
      firebase.auth.EmailAuthProvider.PROVIDER_ID,
      //firebase.auth.FacebookAuthProvider.PROVIDER_ID,
      //firebase.auth.TwitterAuthProvider.PROVIDER_ID,
      //firebase.auth.GithubAuthProvider.PROVIDER_ID,
      //firebase.auth.PhoneAuthProvider.PROVIDER_ID

    ],
    // Terms of service url.
    tosUrl: '<your-tos-url>'
  };

  firebase.auth().onAuthStateChanged(function (user) {
    if (user) {
      // User is signed in, so display the "sign out" button and login info.
      document.getElementById('sign-out').hidden = false;
      document.getElementById('login-info').hidden = false;
      console.log(`Signed in as ${user.displayName} (${user.email})`);
      user.getIdToken().then(function (token) {
        // Add the token to the browser's cookies. The server will then be
        // able to verify the token against the API.
        // SECURITY NOTE: As cookies can easily be modified, only put the
        // token (which is verified server-side) in a cookie; do not add other
        // user information.
        document.cookie = "token=" + token;
      });
    } else {
      // User is signed out.
      // Initialize the FirebaseUI Widget using Firebase.
      var ui = new firebaseui.auth.AuthUI(firebase.auth());
      // Show the Firebase login button.
      ui.start('#firebaseui-auth-container', uiConfig);
      // Update the login state indicators.
      document.getElementById('sign-out').hidden = true;
      document.getElementById('login-info').hidden = true;
      // Clear the token cookie.
      document.cookie = "token=";
    }
  }, function (error) {
    console.log(error);
    alert('Unable to log in: ' + error)
  });
});

Ten en cuenta que el método onAuthStateChanged(), que controla los cambios que se producen cuando un usuario inicia o cierra sesión, almacena el token de ID del usuario como una cookie. Este token de ID es un token único que Firebase genera automáticamente cuando un usuario inicia sesión correctamente. El servidor lo usa para autenticar al usuario.

Actualizar el servicio web para usar tokens

A continuación, verifica a los usuarios en el servidor con su token de ID único de Firebase y, después, descifra su token para que puedas mostrarles sus datos.

Para usar el token de ID de Firebase, sigue estos pasos:

  1. Recupera, verifica y descifra el token en el método root de tu archivo main.py:

    from flask import Flask, render_template, request
    from google.auth.transport import requests
    from google.cloud import datastore
    import google.oauth2.id_token
    
    firebase_request_adapter = requests.Request()
    @app.route("/")
    def root():
        # Verify Firebase auth.
        id_token = request.cookies.get("token")
        error_message = None
        claims = None
        times = None
    
        if id_token:
            try:
                # Verify the token against the Firebase Auth API. This example
                # verifies the token on each page load. For improved performance,
                # some applications may wish to cache results in an encrypted
                # session store (see for instance
                # http://flask.pocoo.org/docs/1.0/quickstart/#sessions).
                claims = google.oauth2.id_token.verify_firebase_token(
                    id_token, firebase_request_adapter
                )
            except ValueError as exc:
                # This will be raised if the token is expired or any other
                # verification checks fail.
                error_message = str(exc)
    
            # Record and fetch the recent times a logged-in user has accessed
            # the site. This is currently shared amongst all users, but will be
            # individualized in a following step.
            store_time(datetime.datetime.now(tz=datetime.timezone.utc))
            times = fetch_times(10)
    
        return render_template(
            "index.html", user_data=claims, error_message=error_message, times=times
        )
    
    
  2. Asegúrate de que tu archivo requirements.txt incluya todas las dependencias necesarias:

    Flask==3.0.0
    google-cloud-datastore==2.15.1
    google-auth==2.17.3
    requests==2.28.2
    

Probar un servicio web

Prueba tu servicio web ejecutándolo de forma local en un entorno virtual:

  1. Ejecuta los siguientes comandos en el directorio principal de tu proyecto para instalar nuevas dependencias y ejecutar tu servicio web. Si no has configurado un entorno virtual para las pruebas locales, consulta cómo probar tu servicio web.

    pip install -r requirements.txt
    python main.py
    
  2. Introduce la siguiente dirección en tu navegador web para ver tu servicio web:

    http://localhost:8080
    

Desplegar un servicio web

Ahora que la autenticación funciona de forma local, puedes volver a desplegar tu servicio web en App Engine.

Ejecuta el siguiente comando desde el directorio raíz de tu proyecto, donde se encuentra el archivo app.yaml:

gcloud app deploy

Todo el tráfico se dirige automáticamente a la nueva versión que has implementado.

Para obtener más información sobre cómo gestionar versiones, consulta el artículo Gestionar servicios y versiones.

Ver tu servicio

Para iniciar rápidamente tu navegador y acceder a tu servicio web en https://PROJECT_ID.REGION_ID.r.appspot.com, ejecuta el siguiente comando:

gcloud app browse

Pasos siguientes

Ahora que has configurado la autenticación de usuarios, puedes aprender a actualizar tu servicio web para personalizar los datos de los usuarios autenticados.