Como gerenciar sessões com o Firestore

Muitos aplicativos precisam gerenciar sessões de autenticação e preferências do usuário. O Sinatra tem uma implementação baseada em memória para executar essa função. No entanto, essa implementação não é adequada para um app que pode ser veiculado de várias instâncias, porque a sessão gravada em uma instância pode ser diferente nas outras. Veja neste tutorial como gerenciar sessões no App Engine.

Objetivos

  • Gravar o aplicativo.
  • Executar o aplicativo localmente.
  • Implantar o aplicativo no App Engine.

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso, use a calculadora de preços.

Novos Google Cloud usuários podem estar qualificados para um teste sem custo financeiro.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Para mais informações, consulte Limpeza.

Antes de começar

  1. Faça login na sua Google Cloud conta do. Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho dos nossos produtos em situações reais. Clientes novos também recebem US $300 em créditos para executar, testar e implantar cargas de trabalho.
  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 Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. 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 Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  8. Prepare seu ambiente de desenvolvimento.

Como configurar o projeto

  1. Na janela de terminal, inicie em um diretório de sua escolha e crie um novo diretório chamado sessions. Todo o código deste tutorial está dentro do diretório sessions.

  2. Mude para o diretório sessions:

    cd sessions
    
  3. Inicialize o Gemfile:

    bundle init
    
  4. Anexe o seguinte ao Gemfile resultante:

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

    O Gemfile lista todas as bibliotecas do Ruby não padrão que seu aplicativo precisa do App Engine para carregar:

    • google-cloud-firestore é o cliente Ruby para a API Firestore.

    • Sinatra é o framework da Web do Ruby usado para o app.

  5. Instale as dependências:

    bundle install
    

Como gravar o app da Web

Esse aplicativo exibe saudações em idiomas diferentes para cada usuário. Os usuários retornantes são sempre recebidos no mesmo idioma.

  • Com um editor de texto, crie um arquivo chamado app.rb no diretório sessions com este conteúdo:

    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

Como criar o armazenamento de sessão

Para que o app possa armazenar as preferências de um usuário, você precisa de uma maneira de armazenar informações sobre o usuário atual em uma sessão. Veja no diagrama a seguir como o Firestore gerencia as sessões do aplicativo do App Engine.

Diagrama da arquitetura: usuário, App Engine, Firestore.

O Sinatra tem suporte integrado para salvar dados da sessão em um cookie. Para salvar no Firestore, é preciso definir seu próprio objeto Rack::Session.

  • No diretório sessions, crie um arquivo chamado firestore_session.rb com este conteúdo:

    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

Como excluir sessões

Conforme descrito, este app não exclui sessões antigas ou expiradas. É possível excluir os dados da sessão no Google Cloud console, ou implementar uma estratégia de exclusão automática.

Como executar no local

  1. Inicie o servidor HTTP:

    bundle exec ruby app.rb
    
  2. Veja seu app no navegador da Web:

    Você verá uma das cinco saudações: "Hello World", "Hallo Welt", "Hola mundo", "Salut le Monde" ou "Ciao Mondo." O idioma será alterado se você abrir a página em um navegador diferente ou no modo de navegação anônima. Veja e edite os dados da sessão no Google Cloud console.

  3. Para interromper o servidor HTTP, pressione Control+C na janela do terminal.

Como implantar e executar no App Engine

Use o ambiente padrão do App Engine para criar e implantar um aplicativo que seja executado de forma confiável sob carga pesada e com grandes quantidades de dados.

Neste tutorial, o ambiente padrão do App Engine é usado para implantar o servidor.

  1. Na sua janela de terminal, crie um arquivo app.yaml e cole o seguinte nele:

    runtime: ruby25
    entrypoint: bundle exec ruby app.rb
  2. Implante o aplicativo no App Engine:

    gcloud app deploy
    
  3. Veja o aplicativo ativo no URL a seguir, em que PROJECT_ID é o Google Cloud ID do projeto:

    https://PROJECT_ID.appspot.com

A saudação agora é entregue por um servidor da Web em execução em uma instância do App Engine.

Como depurar o aplicativo

Se você não conseguir se conectar ao aplicativo do App Engine, verifique o seguinte:

  1. Verifique se os comandos de implantação gcloud foram concluídos com êxito e não geraram erros. Se houver erros (por exemplo, message=Build failed), corrija-os e tente implantar o aplicativo do App Engine novamente.
  2. No Google Cloud console do, acesse a página Análise de registros.

    Acessar a página Análise de registros

    1. Na lista suspensa Recursos selecionados recentemente , clique em Aplicativo App Engine e, em seguida, clique em Todos os module_id. Você verá uma lista de solicitações de quando visitou seu aplicativo. Caso contrário, verifique se você selecionou Todos os module_id na lista suspensa. Se você vir mensagens de erro impressas no Google Cloud console, verifique se o código do seu aplicativo corresponde ao código na seção sobre como gravar o app da Web.

    2. Verifique se a API do Firestore está ativada.

Limpar

Excluir o projeto

  1. No Google Cloud console, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
  3. Na caixa de diálogo, digite o ID do projeto e clique em Desligar para excluir o projeto.

Excluir a instância do App Engine

  1. No Google Cloud console do, acesse a página Versões do App Engine.

    Acessar "Versões"

  2. Marque a caixa de seleção da versão não padrão do app que você quer excluir.
  3. Para excluir a versão do app, clique em Excluir.

A seguir