Autentique utilizadores com o Firebase

ID da região

O REGION_ID é um código abreviado que a Google atribui com base na região que seleciona quando cria a sua app. O código não corresponde a um país ou uma província, embora alguns IDs de regiões possam parecer semelhantes aos códigos de países e províncias usados frequentemente. Para apps criadas após fevereiro de 2020, REGION_ID.r está incluído nos URLs do App Engine. Para apps existentes criadas antes desta data, o ID da região é opcional no URL.

Saiba mais acerca dos IDs de regiões.

Adicione um fluxo de início de sessão de utilizador ao seu serviço Web que use a Firebase Authentication.

Neste passo do guia, atualiza o seu serviço Web para autenticar os utilizadores e para obter e apresentar as informações do utilizador depois de este se autenticar. Tenha em atenção que, para este passo, os tempos de pedido do site continuam a ser globais e não específicos do utilizador.

Antes de começar

Se tiver concluído todos os passos anteriores neste guia, ignore esta secção. Caso contrário, conclua uma das seguintes opções:

  • Comece por Criar uma app Python 3 e conclua todos os passos anteriores a este.

  • Se já tiver um Google Cloud projeto, pode continuar a descarregar uma cópia do serviço Web e adicionar o Firebase:

    1. Transfira o repositório da aplicação de exemplo através do Git:

      git clone https://github.com/GoogleCloudPlatform/python-docs-samples
      

      Em alternativa, pode transferir o exemplo como um ficheiro ZIP e, de seguida, extraí-lo.

    2. Navegue para o diretório que contém uma cópia dos ficheiros do passo anterior:

      cd python-docs-samples/appengine/standard_python3/building-an-app/building-an-app-2
      
    3. Adicione o Firebase ao seu Google Cloud projeto e serviço Web.

Adicione métodos de autenticação do Firebase

O Firebase fornece métodos e variáveis JavaScript que pode usar para configurar o comportamento de início de sessão para o seu serviço Web. Para este serviço Web, adicione uma função de terminar sessão, uma variável que configure a IU de início de sessão e uma função que controle o que muda quando um utilizador inicia ou termina sessão.

Para adicionar os comportamentos necessários para um fluxo de autenticação, substitua o método de ouvinte de eventos atual do ficheiro static/script.js pelo seguinte código:

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

Tenha em atenção que o método onAuthStateChanged(), que controla o que muda quando um utilizador inicia ou termina sessão, armazena o token de ID do utilizador como um cookie. Este token de ID é um token exclusivo que o Firebase gera automaticamente quando um utilizador inicia sessão com êxito e é usado pelo servidor para autenticar o utilizador.

Atualize o seu serviço Web para usar tokens

Em seguida, valide os utilizadores no servidor através do respetivo token de ID do Firebase exclusivo e, de seguida, descifre o token para poder imprimir os dados novamente para os utilizadores.

Para usar o token de ID do Firebase:

  1. Obtenha, valide e desencripte o token no método root do seu ficheiro 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. Certifique-se de que o ficheiro requirements.txt inclui todas as dependências necessárias:

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

Teste o seu serviço Web

Teste o seu serviço Web executando-o localmente num ambiente virtual:

  1. Execute os seguintes comandos no diretório principal do seu projeto para instalar novas dependências e executar o seu serviço Web. Se não configurou um ambiente virtual para testes locais, consulte o artigo sobre como testar o seu serviço Web.

    pip install -r requirements.txt
    python main.py
    
  2. Introduza o seguinte endereço no seu navegador de Internet para ver o serviço Web:

    http://localhost:8080
    

Implemente o seu serviço Web

Agora que a autenticação está a funcionar localmente, pode voltar a implementar o seu serviço Web no App Engine.

Execute o seguinte comando a partir do diretório raiz do seu projeto, onde se encontra o ficheiro app.yaml:

gcloud app deploy

Todo o tráfego é encaminhado automaticamente para a nova versão implementada.

Para mais informações sobre a gestão de versões, consulte o artigo Gerir serviços e versões.

Veja o seu serviço

Para iniciar rapidamente o navegador e aceder ao seu serviço Web em https://PROJECT_ID.REGION_ID.r.appspot.com, execute o seguinte comando:

gcloud app browse

Passos seguintes

Agora que configurou a autenticação de utilizadores, já pode saber como atualizar o seu serviço Web para personalizar os dados para utilizadores autenticados.