Gestione delle sessioni con Firestore

Molte app richiedono la gestione delle sessioni per l'autenticazione e le preferenze utente. Sinatra include un'implementazione basata sulla memoria per eseguire questa funzione. Tuttavia, questa implementazione non è adatta a un'app che può essere pubblicata da più istanze, perché la sessione registrata su un'istanza potrebbe differire da altre istanze. Questo tutorial mostra come gestire le sessioni su App Engine.

Obiettivi

  • Scrivi l'app.
  • Esegui l'app localmente.
  • Esegui il deployment dell'app su App Engine.

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova senza costi.

Al termine delle attività descritte in questo documento, puoi evitare l'addebito di ulteriori costi eliminando le risorse che hai creato. Per saperne di più, consulta Esegui la pulizia.

Prima di iniziare

  1. Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Firestore API.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Firestore API.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  8. Prepara l'ambiente di sviluppo.

Configurazione del progetto

  1. Nella finestra del terminale, inizia in una directory a tua scelta e crea una nuova directory denominata sessions. Tutto il codice per questo tutorial si trova all'interno della directory sessions.

  2. Passa alla directory sessions:

    cd sessions
    
  3. Inizializza Gemfile:

    bundle init
    
  4. Aggiungi quanto segue al Gemfile risultante:

    gem "google-cloud-firestore", "~> 2.0"
    gem "sinatra", "~> 2.0"

    Il Gemfile elenca tutte le librerie Ruby non standard che la tua app deve caricare per App Engine:

    • google-cloud-firestore è il client Ruby per l'API Firestore.

    • Sinatra è il framework web Ruby utilizzato per l'app.

  5. Installa le dipendenze:

    bundle install
    

Scrittura dell'app web

Questa app mostra saluti in lingue diverse per ogni utente. Gli utenti di ritorno vengono sempre accolti nella stessa lingua.

  • Con un editor di testo, crea un file denominato app.rb nella directory sessions con il seguente contenuto:

    require "sinatra"
    
    require_relative "firestore_session"
    
    use Rack::Session::FirestoreSession
    
    set :greetings, ["Hello World", "Hallo Welt", "Ciao Mondo", "Salut le Monde", "Hola Mundo"]
    
    get "/" do
      session[:greeting] ||= settings.greetings.sample
      session[:views] ||= 0
      session[:views] += 1
      "<h1>#{session[:views]} views for \"#{session[:greeting]}\"</h1>"
    end

Creazione dell'archivio delle sessioni

Prima che la tua app possa memorizzare le preferenze di un utente, devi avere un modo per memorizzare le informazioni sull'utente corrente in una sessione. Il seguente diagramma mostra come Firestore gestisce le sessioni per l'app App Engine.

Diagramma dell'architettura: utente, App Engine, Firestore.

Sinatra supporta il salvataggio dei dati di sessione in un cookie. Per salvare in Firestore, devi definire il tuo oggetto Rack::Session.

  • Nella directory sessions, crea un file denominato firestore_session.rb con il seguente contenuto:

    require "google/cloud/firestore"
    require "rack/session/abstract/id"
    
    module Rack
      module Session
        class FirestoreSession < Abstract::Persisted
          def initialize app, options = {}
            super
    
            @firestore = Google::Cloud::Firestore.new
            @col = @firestore.col "sessions"
          end
    
          def find_session _req, session_id
            return [generate_sid, {}] if session_id.nil?
    
            doc = @col.doc session_id
            fields = doc.get.fields || {}
            [session_id, stringify_keys(fields)]
          end
    
          def write_session _req, session_id, new_session, _opts
            doc = @col.doc session_id
            doc.set new_session, merge: true
            session_id
          end
    
          def delete_session _req, session_id, _opts
            doc = @col.doc session_id
            doc.delete
            generate_sid
          end
    
          def stringify_keys hash
            new_hash = {}
            hash.each do |k, v|
              new_hash[k.to_s] =
                if v.is_a? Hash
                  stringify_keys v
                else
                  v
                end
            end
            new_hash
          end
        end
      end
    end

Eliminazione delle sessioni

Così com'è scritta, questa app non elimina le sessioni vecchie o scadute. Puoi eliminare i dati di sessione nella Google Cloud console oppure puoi implementare una strategia di eliminazione automatica.

Esecuzione in locale

  1. Avvia il server HTTP:

    bundle exec ruby app.rb
    
  2. Visualizza l'app nel browser web.

    Viene visualizzato uno dei cinque saluti: "Hello World", "Hallo Welt", "Hola mundo", "Salut le Monde" o "Ciao Mondo". La lingua cambia se apri la pagina in un browser diverso o in modalità di navigazione in incognito. Puoi visualizzare e modificare i dati della sessione nella consoleGoogle Cloud .

  3. Per arrestare il server HTTP, premi Control+C nella finestra del terminale.

Deployment ed esecuzione su App Engine

Puoi utilizzare l'ambiente standard di App Engine per creare ed eseguire il deployment di un'app che funziona in modo affidabile anche se sottoposta a un carico elevato e con grandi quantità di dati.

Questo tutorial utilizza l'ambiente standard di App Engine per eseguire il deployment del server.

  1. Nella finestra del terminale, crea un file app.yaml e incolla quanto segue nel file:

    runtime: ruby25
    entrypoint: bundle exec ruby app.rb
  2. Esegui il deployment dell'app su App Engine:

    gcloud app deploy
    
  3. Visualizza l'app live all'URL seguente, dove PROJECT_ID è l'ID del tuo progetto Google Cloud :

    https://PROJECT_ID.appspot.com

Il saluto viene ora fornito da un server web in esecuzione su un'istanza App Engine.

Esecuzione del debug dell'app

Se non riesci a connetterti alla tua app App Engine, controlla quanto segue:

  1. Verifica che i comandi di deployment gcloud siano stati completati correttamente e non abbiano generato errori. Se si sono verificati errori (ad esempio, message=Build failed), correggili e prova a eseguire di nuovo il deployment dell'app App Engine.
  2. Nella console Google Cloud , vai alla pagina Esplora log.

    Vai alla pagina Esplora log

    1. Nell'elenco a discesa Risorse selezionate di recente, fai clic su Applicazione App Engine e poi su Tutti i module_id. Viene visualizzato un elenco di richieste relative alle tue visite all'app. Se non vedi un elenco di richieste, verifica di aver selezionato Tutti i module_id dall'elenco a discesa. Se visualizzi messaggi di errore stampati nella Google Cloud console, verifica che il codice dell'app corrisponda al codice nella sezione relativa alla scrittura dell'app web.

    2. Assicurati che l'API Firestore sia abilitata.

Esegui la pulizia

Elimina il progetto

  1. Nella console Google Cloud , vai alla pagina Gestisci risorse.

    Vai a Gestisci risorse

  2. Nell'elenco dei progetti, seleziona quello che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID progetto, quindi fai clic su Chiudi per eliminare il progetto.

Elimina l'istanza App Engine

  1. Nella console Google Cloud , vai alla pagina Versioni per App Engine.

    Vai a Versioni

  2. Seleziona la casella di controllo per la versione dell'app non predefinita da eliminare.
  3. Per eliminare la versione dell'app, fai clic su Elimina.

Passaggi successivi