Gestione delle sessioni con Firestore


Questo tutorial mostra come gestire le sessioni su App Engine.

Molte app richiedono la gestione della sessione per l'autenticazione e le preferenze utente. Il pacchetto Gorilla Web Toolkit sessions include un'implementazione basata su file system per eseguire questa funzione. Tuttavia, questa implementazione non è adatta per un'app che può essere pubblicata da più istanze, perché la sessione registrata in un'istanza potrebbe essere diversa da quella di altre istanze. Il pacchetto gorilla/sessions include anche un'implementazione basata sui cookie. Tuttavia, questa implementazione richiede la crittografia dei cookie e l'archiviazione dell'intera sessione sul client, anziché solo un ID sessione, che potrebbe essere troppo grande per alcune app.

Obiettivi

  • Scrivi l'app.
  • Esegui l'app in locale.
  • Eseguire 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 possono essere idonei a una prova senza costi aggiuntivi.

Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina 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 gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
  2. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  3. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  4. Attiva l'API Firestore.

    Abilita l'API

  5. Installa Google Cloud CLI.
  6. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  7. Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.

    Vai al selettore progetti

  8. Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.

  9. Attiva l'API Firestore.

    Abilita l'API

  10. Installa Google Cloud CLI.
  11. Per initialize gcloud CLI, esegui questo comando:

    gcloud init
  12. Aggiorna gcloud componenti:
    gcloud components update
  13. Preparare l'ambiente di sviluppo.

Configurazione del progetto

  1. Nella finestra del terminale, clona il repository dell'app di esempio sulla tua macchina locale:

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git
  2. Passa alla directory che contiene il codice di esempio:

    cd golang-samples/getting-started/sessions

Informazioni sull'app web

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

Diverse finestre di app con un saluto in diverse lingue.

Prima che l'app possa memorizzare le preferenze per un utente, devi avere un modo per memorizzare le informazioni sull'utente corrente in una sessione. Questa app di esempio utilizza Firestore per archiviare i dati delle sessioni.

Puoi utilizzare firestoregorilla, un session store compatibile con gorilla/sessions.

  1. L'app inizia importando le dipendenze, definendo un tipo app che contenga un sessions.Store e un modello HTML, quindi definendo l'elenco di saluti.

    
    // Command sessions starts an HTTP server that uses session state.
    package main
    
    import (
    	"context"
    	"fmt"
    	"html/template"
    	"log"
    	"math/rand"
    	"net/http"
    	"os"
    
    	"cloud.google.com/go/firestore"
    	firestoregorilla "github.com/GoogleCloudPlatform/firestore-gorilla-sessions"
    	"github.com/gorilla/sessions"
    )
    
    // app stores a sessions.Store. Create a new app with newApp.
    type app struct {
    	store sessions.Store
    	tmpl  *template.Template
    }
    
    // greetings are the random greetings that will be assigned to sessions.
    var greetings = []string{
    	"Hello World",
    	"Hallo Welt",
    	"Ciao Mondo",
    	"Salut le Monde",
    	"Hola Mundo",
    }
    
  2. Successivamente, l'app definisce una funzione main, che crea una nuova istanza app, registra il gestore di indice e avvia il server HTTP. La funzione newApp crea l'istanza app inizializzando sessions.Store con la funzione firestoregorilla.New.

    
    func main() {
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = "8080"
    	}
    	projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")
    	if projectID == "" {
    		log.Fatal("GOOGLE_CLOUD_PROJECT must be set")
    	}
    
    	a, err := newApp(projectID)
    	if err != nil {
    		log.Fatalf("newApp: %v", err)
    	}
    
    	http.HandleFunc("/", a.index)
    
    	log.Printf("Listening on port %s", port)
    	if err := http.ListenAndServe(":"+port, nil); err != nil {
    		log.Fatal(err)
    	}
    }
    
    // newApp creates a new app.
    func newApp(projectID string) (*app, error) {
    	ctx := context.Background()
    	client, err := firestore.NewClient(ctx, projectID)
    	if err != nil {
    		log.Fatalf("firestore.NewClient: %v", err)
    	}
    	store, err := firestoregorilla.New(ctx, client)
    	if err != nil {
    		log.Fatalf("firestoregorilla.New: %v", err)
    	}
    
    	tmpl, err := template.New("Index").Parse(`<body>{{.views}} {{if eq .views 1.0}}view{{else}}views{{end}} for "{{.greeting}}"</body>`)
    	if err != nil {
    		return nil, fmt.Errorf("template.New: %w", err)
    	}
    
    	return &app{
    		store: store,
    		tmpl:  tmpl,
    	}, nil
    }
    
  3. Il gestore dell'indice ottiene la sessione dell'utente, creandone una se necessario. Alle nuove sessioni viene assegnato un linguaggio casuale e un numero di visualizzazioni pari a 0. Successivamente, il numero di visualizzazioni viene aumentato di uno, la sessione viene salvata e il modello HTML scrive la risposta.

    
    // index uses sessions to assign users a random greeting and keep track of
    // views.
    func (a *app) index(w http.ResponseWriter, r *http.Request) {
    	if r.RequestURI != "/" {
    		return
    	}
    
    	// name is a non-empty identifier for this app's sessions. Set it to
    	// something descriptive for your app. It is used as the Firestore
    	// collection name that stores the sessions.
    	name := "hello-views"
    	session, err := a.store.Get(r, name)
    	if err != nil {
    		// Could not get the session. Log an error and continue, saving a new
    		// session.
    		log.Printf("store.Get: %v", err)
    	}
    
    	if session.IsNew {
    		// firestoregorilla uses JSON, which unmarshals numbers as float64s.
    		session.Values["views"] = float64(0)
    		session.Values["greeting"] = greetings[rand.Intn(len(greetings))]
    	}
    	session.Values["views"] = session.Values["views"].(float64) + 1
    	if err := session.Save(r, w); err != nil {
    		log.Printf("Save: %v", err)
    		// Don't return early so the user still gets a response.
    	}
    
    	if err := a.tmpl.Execute(w, session.Values); err != nil {
    		log.Printf("Execute: %v", err)
    	}
    }
    

    Il seguente diagramma illustra in che modo Firestore gestisce le sessioni per l'app App Engine.

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

Eliminazione delle sessioni

firestoregorilla non elimina le sessioni vecchie o scadute. Puoi eliminare i dati della sessione nella console Google Cloud o implementare una strategia di eliminazione automatica. Se utilizzi soluzioni di archiviazione per sessioni come Memcache o Redis, le sessioni scadute vengono eliminate automaticamente.

Esecuzione in locale

  1. Nella finestra del terminale, crea il programma binario sessions:

    go build
    
  2. Avvia il server HTTP:

    ./sessions
    
  3. Visualizza l'app nel browser web:

    Cloud Shell

    Nella barra degli strumenti di Cloud Shell, fai clic su Anteprima web Anteprima web e seleziona Anteprima sulla porta 8080.

    Macchina locale

    Nel browser, vai a http://localhost:8080

    Visualizzi 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 console Google Cloud.

    Sessioni Firestore nella console Google Cloud.

  4. 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 viene eseguita 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 il deployment del server.

Il file app.yaml contiene la configurazione dell'ambiente standard di App Engine:

runtime: go112
  1. Esegui il deployment dell'app su App Engine:

    gcloud app deploy
    
  2. Nel browser, inserisci il seguente URL:

    https://PROJECT_ID.REGION_ID.r.appspot.com

    Sostituisci quanto segue:

Ora il saluto viene pubblicato da un server web in esecuzione su un'istanza di App Engine.

Debug dell'app

Se non riesci a connetterti all'app App Engine, verifica quanto segue:

  1. Controlla che i comandi di deployment di gcloud siano stati completati correttamente e non abbiano restituito 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, quindi su All module_id. Viene visualizzato un elenco delle richieste relative al momento in cui hai visitato la tua app. Se non vedi un elenco di richieste, conferma di aver selezionato Tutti i moduli_id dall'elenco a discesa. Se vengono visualizzati messaggi di errore stampati nella console Google Cloud, 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 il progetto che vuoi eliminare, quindi fai clic su Elimina.
  3. Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.

Elimina l'istanza di App Engine

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

    Vai a Versioni

  2. Seleziona la casella di controllo relativa alla versione non predefinita dell'app che vuoi eliminare.
  3. Per eliminare la versione dell'app, fai clic su Elimina.

Passaggi successivi