Gestione delle sessioni con Firestore


Questo tutorial mostra come gestire le sessioni su App Engine.

Molte app richiedono la gestione delle sessioni per l'autenticazione e le preferenze utente. Gorilla Web Toolkit A questo scopo, il pacchetto sessions viene fornito con un'implementazione basata su file system personalizzata. Tuttavia, questa implementazione non è adatta per un'app che può essere pubblicata da più istanze, perché la sessione registrata in un'unica istanza potrebbero essere diverse da altre. Il package gorilla/sessions è dotato anche di un'implementazione basata sui cookie. Ma questa implementazione richiede la crittografia dei cookie e l'archiviazione dell'intera sessione sul client, anziché di un ID sessione, perché potrebbe essere troppo grande per alcune app.

Obiettivi

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

Costi

In questo documento utilizzi i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi basata sull'utilizzo previsto, utilizza il Calcolatore prezzi. I nuovi utenti di Google Cloud potrebbero essere idonei per una prova gratuita.

Al termine delle attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la sezione Pulizia.

Prima di iniziare

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Firestore API.

    Enable the API

  5. Install the Google Cloud CLI.
  6. To initialize the gcloud CLI, run the following command:

    gcloud init
  7. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  8. Make sure that billing is enabled for your Google Cloud project.

  9. Enable the Firestore API.

    Enable the API

  10. Install the Google Cloud CLI.
  11. To initialize the gcloud CLI, run the following command:

    gcloud init
  12. Aggiorna i componenti di gcloud:
    gcloud components update
  13. Prepara 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 lingue diverse per ogni utente. Gli utenti di ritorno vengono sempre accolti nella stessa lingua.

Più finestre di app che mostrano un saluto in lingue diverse.

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

Puoi utilizzare firestoregorilla, un deposito delle sessioni compatibile con gorilla/sessions.

  1. L'app inizia importando le dipendenze, definendo un tipo app per contenere un sessions.Store e un modello HTML e definendo l'elenco dei 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 dell'indice e avvia il server HTTP. newApp crea l'istanza app inizializzando un 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. L'handler dell'indice recupera la sessione dell'utente, creandone una se necessario. Alle nuove sessioni viene assegnato un linguaggio casuale e un numero di visualizzazioni pari a 0. Quindi, il numero di visualizzazioni viene aumentato di uno, la sessione viene salvata e il codice 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&#39;architettura: utente, App Engine, Firestore.

Eliminazione di sessioni

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

Eseguire l'app in locale

  1. Nella finestra del terminale, compila il file binario sessions:

    go build
    
  2. Avvia il server HTTP:

    ./sessions
    
  3. Visualizza l'app nel tuo 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

    Vedi uno di cinque saluti: "Hello World", "Hallo Welt", "Hola mundo", "Salut le Monde" o "Ciao Mondo". La lingua cambia se apri la pagina in un altro browser o in modalità di navigazione in incognito. Puoi visualizzare e modificare i dati di 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 lo Ambiente standard di App Engine per creare ed eseguire il deployment di un'app che viene eseguita in modo affidabile sotto un carico elevato e con quantità di dati.

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

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:

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

Eseguire il debug dell'app

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

  1. Verifica che i comandi di deployment di gcloud siano stati completati correttamente e non abbiano generato errori. Se si sono verificati errori (ad es. message=Build failed), correggili e prova 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 App Engine Application e poi su Tutti i module_id. Viene visualizzato un elenco richieste da quando hai visitato la tua app. Se non vedi l'elenco di richieste, conferma di aver selezionato Tutti i_modulo_id dall'elenco a discesa. Se nella console Google Cloud vengono visualizzati messaggi di errore, verifica che il codice dell'app corrisponda al codice riportato nella sezione relativa alla scrittura dell'app web.

    2. Assicurati che l'API Firestore sia abilitata.

Esegui la pulizia

Elimina il progetto

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Elimina l'istanza App Engine

  1. In the Google Cloud console, go to the Versions page for App Engine.

    Go to Versions

  2. Select the checkbox for the non-default app version that you want to delete.
  3. Per eliminare la versione dell'app, fai clic su Elimina.

Passaggi successivi