Autenticare gli utenti con Firebase

ID regione

REGION_ID è un codice abbreviato assegnato da Google in base alla regione selezionata quando crei l'app. Il codice non corrisponde a un paese o a una provincia, anche se alcuni ID regione possono sembrare simili ai codici di paesi e province di uso comune. Per le app create dopo febbraio 2020, REGION_ID.r è incluso negli URL di App Engine. Per le app esistenti create prima di questa data, l'ID regione è facoltativo nell'URL.

Scopri di più sugli ID regione.

Aggiungi al tuo servizio web un flusso di accesso utente che utilizzi Firebase Authentication.

In questo passaggio della guida, aggiorni il tuo web service per autenticare gli utenti e recuperare e visualizzare le informazioni personali di un utente dopo l'autenticazione. Tieni presente che, per questo passaggio, i tempi di richiesta del sito saranno comunque globali anziché specifici per utente.

Prima di iniziare

Se hai completato tutti i passaggi precedenti di questa guida, salta questa sezione. In caso contrario, completa una delle seguenti operazioni:

Aggiungere metodi di autenticazione Firebase

Firebase fornisce metodi e variabili JavaScript che puoi utilizzare per configurare il comportamento di accesso per il tuo servizio web. Per questo servizio web, aggiungi una funzione di disconnessione, una variabile che configura l'interfaccia utente di accesso e una funzione che controlla cosa cambia quando un utente accede o esce.

Per aggiungere i comportamenti richiesti per un flusso di autenticazione, sostituisci il metodo di gestore degli eventi corrente del file static/script.js con il seguente codice:

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

Tieni presente che il metodo onAuthStateChanged(), che controlla le modifiche quando un utente accede o esce, memorizza il token ID dell'utente come cookie. Questo token ID è un token univoco generato automaticamente da Firebase quando un utente accede correttamente e viene utilizzato dal server per autenticarlo.

Aggiornare il servizio web per utilizzare i token

Successivamente, verifica gli utenti sul server utilizzando il loro token ID Firebase univoco, quindi decripta il token in modo da poter stampare i loro dati.

Per utilizzare l'ID token Firebase:

  1. Recupera, verifica e decripta il token nel metodo root del file 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. Assicurati che il file requirements.txt includa tutte le dipendenze necessarie:

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

Testa il servizio web

Testa il servizio web eseguendolo localmente in un ambiente virtuale:

  1. Esegui i seguenti comandi nella directory principale del progetto per installare nuove dipendenze ed eseguire il servizio web. Se non hai configurato un ambiente virtuale per i test locali, consulta Eseguire il test del servizio web.

    pip install -r requirements.txt
    python main.py
    
  2. Inserisci il seguente indirizzo nel browser web per visualizzare il servizio web:

    http://localhost:8080
    

Deployment del servizio web

Ora che l'autenticazione funziona localmente, puoi eseguire nuovamente il deployment del servizio web in App Engine.

Esegui il comando seguente dalla directory principale del progetto, dove si trova il file app.yaml:

gcloud app deploy

Tutto il traffico viene instradato automaticamente alla nuova versione di cui è stato eseguito il deployment.

Per saperne di più sulla gestione delle versioni, consulta Gestire servizi e versioni.

Visualizza il servizio

Per avviare rapidamente il browser e accedere al servizio web all'indirizzo https://PROJECT_ID.REGION_ID.r.appspot.com, esegui il seguente comando:

gcloud app browse

Passaggi successivi

Ora che hai configurato l'autenticazione utente, puoi scoprire come aggiornare il tuo web service per personalizzare i dati per gli utenti autenticati.