Autenticação do utilizador final para o tutorial do Cloud Run


Este tutorial mostra como criar um serviço de votação composto por:

  • Um cliente baseado no navegador que:

    1. Usa a Identity Platform para obter um token de ID.
    2. Permite que os utilizadores votem no seu animal doméstico favorito.
    3. Adiciona esse token de ID a um pedido ao servidor do Cloud Run que processa o voto.
  • Um servidor do Cloud Run que:

    1. Verifica se o utilizador final se autenticou corretamente fornecendo um token de ID válido.
    2. Processa o voto do utilizador final.
    3. Envia o voto para o Cloud SQL para armazenamento através das suas próprias credenciais.
  • Uma base de dados PostgreSQL que armazena os votos.

Para simplificar, este tutorial usa o Google como um fornecedor: os utilizadores têm de se autenticar através de uma conta Google para adquirir o respetivo token de ID. No entanto, pode usar outros fornecedores ou métodos de autenticação para iniciar sessão nos utilizadores.

Este serviço minimiza os riscos de segurança através do Secret Manager para proteger os dados confidenciais usados para estabelecer ligação à instância do Cloud SQL. Também usa uma identidade de serviço de menor privilégio para proteger o acesso à base de dados.

Objetivos

Escreva, crie e implemente um serviço no Cloud Run que mostre como:

  • Use o Identity Platform para autenticar um utilizador final no back-end do serviço Cloud Run.

  • Crie uma identidade com o mínimo de privilégios para o serviço conceder acesso mínimo aos recursos do Google Cloud .

  • Use o Secret Manager para processar dados sensíveis quando associar o serviço do Cloud Run a uma base de dados PostgreSQL.

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização projetada, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação gratuita.

Antes de começar

  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. Verify that billing is enabled for your Google Cloud project.

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

    Go to project selector

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

  6. Enable the Cloud Run, Secret Manager, Cloud SQL, Artifact Registry, and Cloud Build APIs.

    Enable the APIs

  7. Funções necessárias

    Para receber as autorizações de que precisa para concluir o tutorial, peça ao seu administrador para lhe conceder as seguintes funções da IAM no seu projeto:

    Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.

    Também pode conseguir as autorizações necessárias através de funções personalizadas ou outras funções predefinidas.

Configurar predefinições do gcloud

Para configurar o gcloud com as predefinições do seu serviço do Cloud Run:

  1. Defina o projeto predefinido:

    gcloud config set project PROJECT_ID

    Substitua PROJECT_ID pelo nome do projeto que criou para este tutorial.

  2. Configure o gcloud para a região escolhida:

    gcloud config set run/region REGION

    Substitua REGION pela região do Cloud Run suportada à sua escolha.

Localizações do Cloud Run

O Cloud Run é regional, o que significa que a infraestrutura que executa os seus serviços do Cloud Run está localizada numa região específica e é gerida pela Google para estar disponível de forma redundante em todas as zonas dessa região.

O cumprimento dos requisitos de latência, disponibilidade ou durabilidade são fatores principais para selecionar a região onde os seus serviços do Cloud Run são executados. Geralmente, pode selecionar a região mais próxima dos seus utilizadores, mas deve considerar a localização dos outros Google Cloudprodutos usados pelo seu serviço do Cloud Run. A utilização Google Cloud de produtos em conjunto em várias localizações pode afetar a latência do seu serviço, bem como o custo.

O Cloud Run está disponível nas seguintes regiões:

Sujeito aos preços de Nível 1

  • asia-east1 (Taiwan)
  • asia-northeast1 (Tóquio)
  • asia-northeast2 (Osaca)
  • asia-south1 (Mumbai, Índia)
  • europe-north1 (Finlândia) ícone de folha Baixo CO2
  • europe-north2 (Estocolmo) ícone de folha Baixo CO2
  • europe-southwest1 (Madrid) ícone de folha Baixo CO2
  • europe-west1 (Bélgica) ícone de folha Baixo CO2
  • europe-west4 (Países Baixos) ícone de folha Baixo CO2
  • europe-west8 (Milão)
  • europe-west9 (Paris) ícone de folha Baixo CO2
  • me-west1 (Telavive)
  • northamerica-south1 (México)
  • us-central1 (Iowa) ícone de folha Baixo CO2
  • us-east1 (Carolina do Sul)
  • us-east4 (Virgínia do Norte)
  • us-east5 (Columbus)
  • us-south1 (Dallas) ícone de folha Baixo CO2
  • us-west1 (Oregão) ícone de folha Baixo CO2

Sujeito aos preços de Nível 2

  • africa-south1 (Joanesburgo)
  • asia-east2 (Hong Kong)
  • asia-northeast3 (Seul, Coreia do Sul)
  • asia-southeast1 (Singapura)
  • asia-southeast2 (Jacarta)
  • asia-south2 (Deli, Índia)
  • australia-southeast1 (Sydney)
  • australia-southeast2 (Melbourne)
  • europe-central2 (Varsóvia, Polónia)
  • europe-west10 (Berlim) ícone de folha Baixo CO2
  • europe-west12 (Turim)
  • europe-west2 (Londres, Reino Unido) ícone de folha Baixo CO2
  • europe-west3 (Frankfurt, Alemanha)
  • europe-west6 (Zurique, Suíça) ícone de folha Baixo CO2
  • me-central1 (Doha)
  • me-central2 (Dammam)
  • northamerica-northeast1 (Montreal) ícone de folha Baixo CO2
  • northamerica-northeast2 (Toronto) ícone de folha Baixo CO2
  • southamerica-east1 (São Paulo, Brasil) ícone de folha Baixo CO2
  • southamerica-west1 (Santiago, Chile) ícone de folha Baixo CO2
  • us-west2 (Los Angeles)
  • us-west3 (Salt Lake City)
  • us-west4 (Las Vegas)

Se já criou um serviço do Cloud Run, pode ver a região no painel de controlo do Cloud Run na Google Cloud consola.

Obter o exemplo de código

Para obter o exemplo de código para utilização:

  1. Clone o repositório da app de exemplo para a sua máquina local:

    Node.js

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

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

    Python

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

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

    Java

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

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

  2. Altere para o diretório que contém o código de exemplo do Cloud Run:

    Node.js

    cd nodejs-docs-samples/run/idp-sql/

    Python

    cd python-docs-samples/run/idp-sql/

    Java

    cd java-docs-samples/run/idp-sql/

Visualizar a arquitetura

Diagrama arquitetónico
O diagrama mostra um utilizador final a iniciar sessão através de uma caixa de diálogo de início de sessão da Google fornecida pela Identity Platform e, em seguida, a ser redirecionado de volta para o Cloud Run com a identidade do utilizador.
  1. Um utilizador final faz o primeiro pedido ao servidor do Cloud Run.

  2. O cliente é carregado no navegador.

  3. O utilizador fornece credenciais de início de sessão através da caixa de diálogo de início de sessão do Google a partir da Identity Platform. Um alerta dá as boas-vindas ao utilizador com sessão iniciada.

  4. O controlo é redirecionado de volta para o servidor. O utilizador final vota através do cliente, que obtém um token de ID da Identity Platform e adiciona-o ao cabeçalho do pedido de voto.

  5. Quando o servidor recebe o pedido, valida o token de ID da Identity Platform, confirmando que o utilizador final está devidamente autenticado. Em seguida, o servidor envia o voto para o Cloud SQL através das suas próprias credenciais.

Compreender o código principal

O exemplo é implementado como cliente e servidor, conforme descrito a seguir.

Integração com o Identity Platform: código do lado do cliente

Este exemplo usa SDKs do Firebase para integrar com a Identity Platform de modo a iniciar sessão e gerir utilizadores. Para se ligar à Identity Platform, o JavaScript do lado do cliente contém a referência às credenciais do projeto como um objeto de configuração e importa os SDKs Firebase JavaScript necessários:

const config = {
  apiKey: 'API_KEY',
  authDomain: 'PROJECT_ID.firebaseapp.com',
};
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first-->
<script src="https://www.gstatic.com/firebasejs/7.18/firebase-app.js"></script>
<!-- Add Firebase Auth service-->
<script src="https://www.gstatic.com/firebasejs/7.18/firebase-auth.js"></script>

O SDK do JavaScript do Firebase processa o fluxo de início de sessão pedindo ao utilizador final que inicie sessão na respetiva Conta Google através de uma janela de pop-up. Em seguida, redireciona-os de volta para o serviço.

function signIn() {
  const provider = new firebase.auth.GoogleAuthProvider();
  provider.addScope('https://www.googleapis.com/auth/userinfo.email');
  firebase
    .auth()
    .signInWithPopup(provider)
    .then(result => {
      // Returns the signed in user along with the provider's credential
      console.log(`${result.user.displayName} logged in.`);
      window.alert(`Welcome ${result.user.displayName}!`);
    })
    .catch(err => {
      console.log(`Error during sign in: ${err.message}`);
      window.alert('Sign in failed. Retry or check your browser logs.');
    });
}

Quando um utilizador inicia sessão com êxito, o cliente usa métodos do Firebase para gerar um token de ID. O cliente adiciona o token de ID ao cabeçalho Authorization do respetivo pedido ao servidor.

async function vote(team) {
  if (firebase.auth().currentUser) {
    // Retrieve JWT to identify the user to the Identity Platform service.
    // Returns the current token if it has not expired. Otherwise, this will
    // refresh the token and return a new one.
    try {
      const token = await firebase.auth().currentUser.getIdToken();
      const response = await fetch('/', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          Authorization: `Bearer ${token}`,
        },
        body: 'team=' + team, // send application data (vote)
      });
      if (response.ok) {
        const text = await response.text();
        window.alert(text);
        window.location.reload();
      }
    } catch (err) {
      console.log(`Error when submitting vote: ${err}`);
      window.alert('Something went wrong... Please try again!');
    }
  } else {
    window.alert('User not signed in.');
  }
}

Integração com a Identity Platform: código do lado do servidor

O servidor usa o SDK Firebase Admin para validar o token de ID do utilizador enviado a partir do cliente. Se o token de ID fornecido tiver o formato correto, não estiver expirado e estiver devidamente assinado, o método devolve o token de ID descodificado. O servidor extrai o Identity Platform uid para esse utilizador.

Node.js

const firebase = require('firebase-admin');
// Initialize Firebase Admin SDK
firebase.initializeApp();

// Extract and verify Id Token from header
const authenticateJWT = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    const token = authHeader.split(' ')[1];
    // If the provided ID token has the correct format, is not expired, and is
    // properly signed, the method returns the decoded ID token
    firebase
      .auth()
      .verifyIdToken(token)
      .then(decodedToken => {
        const uid = decodedToken.uid;
        req.uid = uid;
        next();
      })
      .catch(err => {
        req.logger.error(`Error with authentication: ${err}`);
        return res.sendStatus(403);
      });
  } else {
    return res.sendStatus(401);
  }
};

Python

def jwt_authenticated(func: Callable[..., int]) -> Callable[..., int]:
    """Use the Firebase Admin SDK to parse Authorization header to verify the
    user ID token.

    The server extracts the Identity Platform uid for that user.
    """

    @wraps(func)
    def decorated_function(*args: a, **kwargs: a) -> a:
        header = request.headers.get("Authorization", None)
        if header:
            token = header.split(" ")[1]
            try:
                decoded_token = firebase_admin.auth.verify_id_token(token)
            except Exception as e:
                logger.exception(e)
                return Response(status=403, response=f"Error with authentication: {e}")
        else:
            return Response(status=401)

        request.uid = decoded_token["uid"]
        return func(*args, **kwargs)

    return decorated_function

Java

/** Extract and verify Id Token from header */
private String authenticateJwt(Map<String, String> headers) {
  String authHeader =
      (headers.get("authorization") != null)
          ? headers.get("authorization")
          : headers.get("Authorization");
  if (authHeader != null) {
    String idToken = authHeader.split(" ")[1];
    // If the provided ID token has the correct format, is not expired, and is
    // properly signed, the method returns the decoded ID token
    try {
      FirebaseToken decodedToken = FirebaseAuth.getInstance().verifyIdToken(idToken);
      String uid = decodedToken.getUid();
      return uid;
    } catch (FirebaseAuthException e) {
      logger.error("Error with authentication: " + e.toString());
      throw new ResponseStatusException(HttpStatus.FORBIDDEN, "", e);
    }
  } else {
    logger.error("Error no authorization header");
    throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
  }
}

Ligar o servidor ao Cloud SQL

O servidor liga-se ao socket de domínio Unix da instância do Cloud SQL através do formato: /cloudsql/CLOUD_SQL_CONNECTION_NAME.

Node.js

/**
 * Connect to the Cloud SQL instance through UNIX Sockets
 *
 * @param {object} credConfig The Cloud SQL connection configuration from Secret Manager
 * @returns {object} Knex's PostgreSQL client
 */
const connectWithUnixSockets = async credConfig => {
  const dbSocketPath = process.env.DB_SOCKET_PATH || '/cloudsql';
  // Establish a connection to the database
  return Knex({
    client: 'pg',
    connection: {
      user: credConfig.DB_USER, // e.g. 'my-user'
      password: credConfig.DB_PASSWORD, // e.g. 'my-user-password'
      database: credConfig.DB_NAME, // e.g. 'my-database'
      host: `${dbSocketPath}/${credConfig.CLOUD_SQL_CONNECTION_NAME}`,
    },
    ...config,
  });
};

Python

def init_unix_connection_engine(
    db_config: dict[str, int]
) -> sqlalchemy.engine.base.Engine:
    """Initializes a Unix socket connection pool for a Cloud SQL instance of PostgreSQL.

    Args:
        db_config: a dictionary with connection pool config

    Returns:
        A SQLAlchemy Engine instance.
    """
    creds = credentials.get_cred_config()
    db_user = creds["DB_USER"]
    db_pass = creds["DB_PASSWORD"]
    db_name = creds["DB_NAME"]
    db_socket_dir = creds.get("DB_SOCKET_DIR", "/cloudsql")
    cloud_sql_connection_name = creds["CLOUD_SQL_CONNECTION_NAME"]

    pool = sqlalchemy.create_engine(
        # Equivalent URL:
        # postgres+pg8000://<db_user>:<db_pass>@/<db_name>
        #                         ?unix_sock=<socket_path>/<cloud_sql_instance_name>/.s.PGSQL.5432
        sqlalchemy.engine.url.URL.create(
            drivername="postgresql+pg8000",
            username=db_user,  # e.g. "my-database-user"
            password=db_pass,  # e.g. "my-database-password"
            database=db_name,  # e.g. "my-database-name"
            query={
                "unix_sock": f"{db_socket_dir}/{cloud_sql_connection_name}/.s.PGSQL.5432"
                # e.g. "/cloudsql", "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
            },
        ),
        **db_config,
    )
    pool.dialect.description_encoding = None
    logger.info("Database engine initialized from unix connection")

    return pool

Java

Use a integração do Spring Cloud Google Cloud PostgreSQL starter para interagir com as suas bases de dados PostgreSQL no Cloud SQL através das bibliotecas Spring JDBC. Defina a configuração do Cloud SQL para MySQL para configurar automaticamente um bean DataSource que, juntamente com o Spring JDBC, fornece um bean de objeto JdbcTemplate que permite operações como consultar e modificar uma base de dados.

# Uncomment and add env vars for local development
# spring.datasource.username=${DB_USER}
# spring.datasource.password=${DB_PASSWORD}
# spring.cloud.gcp.sql.database-name=${DB_NAME}
# spring.cloud.gcp.sql.instance-connection-name=${CLOUD_SQL_CONNECTION_NAME}  
private final JdbcTemplate jdbcTemplate;

public VoteController(JdbcTemplate jdbcTemplate) {
  this.jdbcTemplate = jdbcTemplate;
}

Processamento de configurações confidenciais com o Secret Manager

O Secret Manager oferece armazenamento centralizado e seguro de dados confidenciais, como a configuração do Cloud SQL. O servidor injeta as credenciais do Cloud SQL do Secret Manager no tempo de execução através de uma variável de ambiente. Saiba mais sobre a utilização de segredos com o Cloud Run.

Node.js

// CLOUD_SQL_CREDENTIALS_SECRET is the resource ID of the secret, passed in by environment variable.
// Format: projects/PROJECT_ID/secrets/SECRET_ID/versions/VERSION
const {CLOUD_SQL_CREDENTIALS_SECRET} = process.env;
if (CLOUD_SQL_CREDENTIALS_SECRET) {
  try {
    // Parse the secret that has been added as a JSON string
    // to retrieve database credentials
    return JSON.parse(CLOUD_SQL_CREDENTIALS_SECRET.toString('utf8'));
  } catch (err) {
    throw Error(
      `Unable to parse secret from Secret Manager. Make sure that the secret is JSON formatted: ${err}`
    );
  }
}

Python

def get_cred_config() -> dict[str, str]:
    """Retrieve Cloud SQL credentials stored in Secret Manager
    or default to environment variables.

    Returns:
        A dictionary with Cloud SQL credential values
    """
    secret = os.environ.get("CLOUD_SQL_CREDENTIALS_SECRET")
    if secret:
        return json.loads(secret)

Java

/** Retrieve config from Secret Manager */
public static HashMap<String, Object> getConfig() {
  String secret = System.getenv("CLOUD_SQL_CREDENTIALS_SECRET");
  if (secret == null) {
    throw new IllegalStateException("\"CLOUD_SQL_CREDENTIALS_SECRET\" is required.");
  }
  try {
    HashMap<String, Object> config = new Gson().fromJson(secret, HashMap.class);
    return config;
  } catch (JsonSyntaxException e) {
    logger.error(
        "Unable to parse secret from Secret Manager. Make sure that it is JSON formatted: "
            + e);
    throw new RuntimeException(
        "Unable to parse secret from Secret Manager. Make sure that it is JSON formatted.");
  }
}

Configure o Identity Platform

O Identity Platform requer configuração manual na Google Cloud consola.

  1. Na Google Cloud consola, ative a API Identity Platform:

    Ative a API

  2. Configure o seu projeto:

    1. Numa nova janela, aceda à página Google Auth Platform > Vista geral.

      Aceda à Vista geral

    2. Clique em Começar e siga a configuração do projeto.

    3. Na caixa de diálogo Informações da app:

      1. Indique o nome da aplicação.
      2. Selecione um dos emails de apoio técnico ao utilizador apresentados.
    4. Na caixa de diálogo Público-alvo, selecione Externo.

    5. Na caixa de diálogo Informações de contacto, introduza um email de contacto.

    6. Aceite a política de dados do utilizador e, de seguida, clique em Criar.

  3. Crie e obtenha o ID de cliente e o segredo do cliente OAuth:

    1. Na Google Cloud consola, aceda à página APIs e serviços > Credenciais.

      Aceder a Credenciais

    2. Na parte superior da página, clique em Criar credenciais e selecione OAuth client ID.

    3. Em Tipo de aplicação, selecione Aplicação Web e indique o nome.

    4. Clique em Criar

    5. Os valores client_id e client_secret vão ser usados no passo seguinte.

  4. Configure o Google como fornecedor:

    1. Na Google Cloud consola, aceda à página Fornecedores de identidade.

      Aceder a Fornecedores de identidade

    2. Clique em Adicionar um fornecedor.

    3. Selecione Google na lista.

    4. Nas definições de configuração do SDK Web, introduza os valores client_id e client_secret do passo anterior.

    5. Em Configure a sua aplicação, clique em Detalhes da configuração.

  5. Copie a configuração para a sua aplicação:

    • Copie os valores apiKey e authDomain para o static/config.js da amostra para inicializar o SDK do cliente da Identity Platform.

Implementar o serviço

Siga os passos para concluir o aprovisionamento e a implementação da infraestrutura:

  1. Crie uma instância do Cloud SQL com a base de dados PostgreSQL através da consola ou da CLI:

    gcloud sql instances create CLOUD_SQL_INSTANCE_NAME \
        --database-version=POSTGRES_16 \
        --region=CLOUD_SQL_REGION \
        --cpu=2 \
        --memory=7680MB \
        --root-password=DB_PASSWORD
  2. Adicione os valores das credenciais do Cloud SQL a postgres-secrets.json:

    Node.js

    {
      "CLOUD_SQL_CONNECTION_NAME": "PROJECT_ID:REGION:INSTANCE",
      "DB_NAME": "postgres",
      "DB_USER": "postgres",
      "DB_PASSWORD": "PASSWORD_SECRET"
    }
    

    Python

    {
      "CLOUD_SQL_CONNECTION_NAME": "PROJECT_ID:REGION:INSTANCE",
      "DB_NAME": "postgres",
      "DB_USER": "postgres",
      "DB_PASSWORD": "PASSWORD_SECRET"
    }
    

    Java

    {
      "spring.cloud.gcp.sql.instance-connection-name": "PROJECT_ID:REGION:INSTANCE",
      "spring.cloud.gcp.sql.database-name": "postgres",
      "spring.datasource.username": "postgres",
      "spring.datasource.password": "PASSWORD_SECRET"
    }

  3. Crie um segredo com versões através da consola ou da CLI:

    gcloud secrets create idp-sql-secrets \
        --replication-policy="automatic" \
        --data-file=postgres-secrets.json
  4. Crie uma conta de serviço para o servidor através da consola ou da CLI:

    gcloud iam service-accounts create idp-sql-identity
  5. Conceda funções para o Secret Manager e o acesso ao Cloud SQL através da consola ou da CLI:

    1. Permita que a conta de serviço associada ao servidor aceda ao segredo criado:

      gcloud secrets add-iam-policy-binding idp-sql-secrets \
        --member serviceAccount:idp-sql-identity@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/secretmanager.secretAccessor
    2. Permita que a conta de serviço associada ao servidor aceda ao Cloud SQL:

      gcloud projects add-iam-policy-binding PROJECT_ID \
        --member serviceAccount:idp-sql-identity@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/cloudsql.client
  6. Crie um Artifact Registry:

    gcloud artifacts repositories create REPOSITORY \
        --repository-format docker \
        --location REGION
    • REPOSITORY é o nome do repositório. Para cada localização do repositório num projeto, os nomes dos repositórios têm de ser exclusivos.
  7. Crie a imagem de contentor com o Cloud Build:

    Node.js

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql

    Python

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql

    Java

    Este exemplo usa o Jib para criar imagens do Docker com ferramentas Java comuns. O Jib otimiza as compilações de contentores sem precisar de um Dockerfile nem ter o Docker instalado. Saiba mais sobre como criar contentores Java com o Jib.

    1. Use o auxiliar de credenciais gcloud para autorizar o Docker a enviar para o seu Artifact Registry.

      gcloud auth configure-docker

    2. Use o plugin Jib Maven para criar e enviar o contentor para o Artifact Registry.

      mvn compile jib:build -Dimage=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql

  8. Implemente a imagem do contentor no Cloud Run através da consola ou da CLI. Tenha em atenção que o servidor é implementado para permitir o acesso não autenticado. Isto permite que o utilizador carregue o cliente e inicie o processo. O servidor valida manualmente o token de ID adicionado ao pedido de voto, autenticando o utilizador final.

    gcloud run deploy idp-sql \
        --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/idp-sql \
        --allow-unauthenticated \
        --service-account idp-sql-identity@PROJECT_ID.iam.gserviceaccount.com \
        --add-cloudsql-instances PROJECT_ID:REGION:CLOUD_SQL_INSTANCE_NAME \
        --update-secrets CLOUD_SQL_CREDENTIALS_SECRET=idp-sql-secrets:latest

    Tenha também em atenção as flags --service-account, --add-cloudsql-instances e --update-secrets, que especificam a identidade do serviço, a ligação da instância do Cloud SQL e o nome do segredo com a versão como uma variável de ambiente, respetivamente.

Toques finais

A Identity Platform requer que autorize o URL do serviço do Cloud Run como um redirecionamento permitido depois de o utilizador ter iniciado sessão:

  1. Edite o fornecedor Google clicando no ícone de caneta na página Fornecedores de identidade.

  2. Clique em Adicionar domínio em Domínios autorizados no painel do lado direito e introduza o URL do serviço do Cloud Run.

    Pode localizar o URL do serviço nos registos após a compilação ou a implementação, ou pode encontrá-lo em qualquer altura através do seguinte comando:

    gcloud run services describe idp-sql --format 'value(status.url)'
  3. Aceda à página APIs e serviços > Credenciais

    1. Clique no ícone de lápis junto ao ID de cliente OAuth para o editar e abaixo do botão Authorized redirect URIs click the Adicionar URI.

    2. No campo, copie e cole o seguinte URL e clique no botão Guardar na parte inferior da página.

    https://PROJECT_ID.firebaseapp.com/__/auth/handler

Experimentar

Para experimentar o serviço completo:

  1. Navegue no navegador para o URL fornecido no passo de implementação acima.

  2. Clique no botão Iniciar sessão com o Google e conclua o fluxo de autenticação.

  3. Adicione o seu voto!

    Deve ter esta forma:

    A interface do utilizador mostra a contagem de votos de cada equipa e uma lista de votos.

Se optar por continuar a desenvolver estes serviços, lembre-se de que têm acesso restrito à gestão de identidade e acesso (IAM) ao resto do Google Cloud e terão de receber funções adicionais de IAM para aceder a muitos outros serviços.

Limpar

Se criou um novo projeto para este tutorial, elimine o projeto. Se usou um projeto existente e quer mantê-lo sem as alterações adicionadas neste tutorial, elimine os recursos criados para o tutorial.

Eliminar o projeto

A forma mais fácil de eliminar a faturação é eliminar o projeto que criou para o tutorial.

Para eliminar o projeto:

  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.

Eliminar recursos do tutorial

  1. Elimine o serviço do Cloud Run que implementou neste tutorial:

    gcloud run services delete SERVICE-NAME

    Onde SERVICE-NAME é o nome do serviço escolhido.

    Também pode eliminar serviços do Cloud Run a partir da Google Cloud consola.

  2. Remova a configuração da região predefinida do gcloud que adicionou durante a configuração do tutorial:

     gcloud config unset run/region
    
  3. Remova a configuração do projeto:

     gcloud config unset project
    
  4. Elimine outros Google Cloud recursos criados neste tutorial:

O que se segue?