Autentique e associe a uma base de dados

Requisitos de ligação

Os seguintes elementos são necessários para clientes do Firestore com compatibilidade com o MongoDB:

  • Os condutores têm de estabelecer ligação no modo load balanced. Isto impede que os controladores tentem compreender a topologia exata do servidor ao qual se estão a ligar.
  • Os condutores têm de estabelecer ligação com o SSL ativado.
  • Os controladores têm de desativar as escritas repetíveis. O Firestore com compatibilidade com o MongoDB não suporta escritas repetíveis. Não precisa de desativar as leituras repetíveis, uma vez que são suportadas.

Obtenha a string de ligação

A cadeia de caracteres da ligação à base de dados depende do UID da base de dados, da localização da base de dados e do mecanismo de autenticação. As instruções seguintes descrevem como a string de ligação é formada.

A string de ligação exata depende do mecanismo de autenticação, mas a string de ligação base usa o seguinte formato:

mongodb://UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&tls=true&retryWrites=false

Pode obter a string de ligação base de uma das seguintes formas:

Consola
  1. Na Google Cloud consola, aceda à página Bases de dados.

    Aceda a Bases de dados

  2. Na lista de bases de dados, clique no ID da base de dados relevante.
  3. O painel Explorador apresenta a string de ligação base. Copie e use esta string de ligação para se ligar à sua base de dados.
gcloud

Use gcloud firestore database describe para obter o UID e as informações de localização:

gcloud firestore databases describe \
--database=DATABASE_ID \
--format='yaml(locationId, uid)'

Substitua DATABASE_ID pelo ID da base de dados.

A saída inclui a localização e o UID da base de dados. Use estas informações para criar a string de ligação base.

Use a string de ligação base e um dos seguintes métodos para autenticar e estabelecer ligação à sua base de dados:

Estabeleça ligação com o nome de utilizador e a palavra-passe (SCRAM)

Siga estes passos para criar uma credencial de utilizador para a sua base de dados e estabelecer ligação à base de dados.

Antes de começar

Para receber as autorizações de que precisa para criar um utilizador, peça ao seu administrador que lhe conceda a função userCredsAdmin (roles/datastore.userCredsAdmin) IAM na sua base de dados. 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.

Crie um utilizador e ligue-o a uma base de dados

Para criar um utilizador para a sua base de dados do Firestore com compatibilidade com o MongoDB, use um dos seguintes métodos:

Google Cloud consola
  1. Na Google Cloud consola, aceda à página Bases de dados.

    Aceda a Bases de dados

  2. Selecione uma base de dados na lista de bases de dados.
  3. No menu de navegação, clique em Auth.
  4. Clique em Adicionar utilizador.
  5. Introduza um Nome de utilizador.
  6. Selecione uma função para o novo utilizador.
  7. Clique em Adicionar.

    A palavra-passe do novo utilizador é apresentada na caixa de diálogo de confirmação.

CLI gcloud
  1. Para autenticar com SCRAM, tem de criar primeiro uma credencial de utilizador. Use o comando gcloud firestore user-creds:
    gcloud firestore user-creds create USERNAME --database=DATABASE_ID
    Substitua o seguinte:
    • USERNAME: o nome de utilizador a criar.
    • DATABASE_ID: o ID da base de dados.

    O resultado deste comando inclui a palavra-passe do utilizador.

    O resultado é semelhante ao seguinte:

    name: projects/PROJECT_NAME/databases/DATABASE_ID/userCreds/USERNAME
    resourceIdentity:
      principal: principal://firestore.googleapis.com/projects/PROJECT_NUMBER/name/databases/DATABASE_ID/userCreds/USERNAME
    securePassword: PASSWORD
  2. Por predefinição, esta nova credencial de utilizador não tem autorizações. Para ter acesso de leitura e escrita à base de dados, adicione a função roles/datastore.user para esta base de dados específica:

    gcloud projects add-iam-policy-binding PROJECT_NAME \
    --member='principal://firestore.googleapis.com/projects/PROJECT_NUMBER/name/databases/DATABASE_ID/userCreds/USERNAME' \
    --role=roles/datastore.user \
    --condition='expression=resource.name == "projects/PROJECT_NAME/databases/DATABASE_ID",title="CONDITION_TITLE"'
    Substitua o seguinte:
Java

Esta secção fornece um exemplo de código para criar credenciais de utilizador e configurar a política de IAM através de bibliotecas cliente administrativas Java. O exemplo usa a biblioteca Firestore Admin Client para criar um nome de utilizador e uma palavra-passe, e a biblioteca Google Cloud Resource Manager para configurar o IAM.

Para compilações do Maven, pode usar as seguintes coordenadas:

com.google.cloud:google-cloud-firestore-admin:3.33.1
com.google.cloud:google-cloud-resourcemanager:1.76.0

Aprovisione credenciais de utilizador e uma política IAM:

import com.google.cloud.firestore.v1.FirestoreAdminClient;
import com.google.cloud.resourcemanager.v3.ProjectName;
import com.google.cloud.resourcemanager.v3.ProjectsClient;
import com.google.firestore.admin.v1.CreateUserCredsRequest;
import com.google.firestore.admin.v1.GetUserCredsRequest;
import com.google.firestore.admin.v1.UserCreds;
import com.google.iam.v1.Binding;
import com.google.iam.v1.GetIamPolicyRequest;
import com.google.iam.v1.GetPolicyOptions;
import com.google.iam.v1.Policy;
import com.google.iam.v1.SetIamPolicyRequest;
import com.google.protobuf.FieldMask;
import com.google.type.Expr;

public class FirestoreUserCredsExample {
  /**
   * Provision user credentials and configure an IAM policy to allow SCRAM authentication into the
   * specified Firestore with Mongo Compatibility database.
   */
  private static void provisionFirestoreUserCredsAndIAM(
      String projectId, String databaseId, String userName) throws Exception {
    UserCreds userCreds = createUserCreds(projectId, databaseId, userName);

    // Note the password returned in the UserCreds proto - it cannot be retrieved again
    // after the initial call to the createUserCreds API.
    System.out.printf(
        "Created credentials for username: %s:\nIAM principal: %s\nPassword: [%s]\n",
        userName, userCreds.getResourceIdentity().getPrincipal(), userCreds.getSecurePassword());

    // Provision an IAM binding for the principal associated with these user credentials.
    updateIamPolicyForUserCreds(projectId, databaseId, userName, userCreds);

    // Emit the password again.
    System.out.printf(
        "Successfully configured IAM policy for database: %s, username: %s\n",
        databaseId, userName);
    System.out.printf("Please make a note of the password: [%s]\n", userCreds.getSecurePassword());
  }

  /** Provision new user credentials using the FirestoreAdminClient. */
  private static UserCreds createUserCreds(String projectId, String databaseId, String userName)
      throws Exception {
    FirestoreAdminClient firestoreAdminClient = FirestoreAdminClient.create();
    return firestoreAdminClient.createUserCreds(
        CreateUserCredsRequest.newBuilder()
            .setParent(String.format("projects/%s/databases/%s", projectId, databaseId))
            .setUserCredsId(userName)
            .build());
  }

  /** Update the IAM policy using the Resource Manager ProjectsClient. */
  private static void updateIamPolicyForUserCreds(
      String projectId, String databaseId, String userName, UserCreds userCreds) throws Exception {
    try (ProjectsClient projectsClient = ProjectsClient.create()) {
      ProjectName projectName = ProjectName.of(projectId);

      // Get the current IAM policy.
      Policy currentPolicy =
          projectsClient.getIamPolicy(
              GetIamPolicyRequest.newBuilder()
                  .setResource(projectName.toString())
                  .setOptions(GetPolicyOptions.newBuilder().setRequestedPolicyVersion(3).build())
                  .build());

      String role = "roles/datastore.user";
      String title = String.format("Conditional IAM binding for %s", userName);
      String expression =
          String.format("resource.name == \"projects/%s/databases/%s\"", projectId, databaseId);

      // Construct an updated IAM policy with an additional binding for the user credentials.
      Policy.Builder policyBuilder = currentPolicy.toBuilder();
      Binding newBinding =
          Binding.newBuilder()
              .setRole(role)
              .setCondition(Expr.newBuilder().setTitle(title).setExpression(expression).build())
              .addMembers(userCreds.getResourceIdentity().getPrincipal())
              .build();
      policyBuilder.addBindings(newBinding);

      // Update the policy
      SetIamPolicyRequest request =
          SetIamPolicyRequest.newBuilder()
              .setResource(projectName.toString())
              .setPolicy(policyBuilder.build())
              .setUpdateMask(FieldMask.newBuilder().addPaths("bindings").addPaths("etag").build())
              .build();
      System.out.println(request);

      Policy updatedPolicy = projectsClient.setIamPolicy(request);
      System.out.println("Policy updated successfully: " + updatedPolicy);
    }
  }
}
Python

Esta secção fornece um exemplo de código para criar credenciais de utilizador e configurar a política de IAM através de bibliotecas cliente administrativas Python. O exemplo usa a biblioteca cliente da API Google Cloud Firestore para criar um nome de utilizador e uma palavra-passe, e a biblioteca cliente da API Google Cloud IAM e a biblioteca cliente da API Google Cloud Resource Manager para configurar a IAM.

As bibliotecas Python necessárias podem ser instaladas com a ferramenta pip:

pip install google-cloud-iam
pip install google-cloud-firestore
pip install google-cloud-resource-manager

Aprovisione credenciais de utilizador e uma política IAM:

from google.cloud import resourcemanager_v3
from google.cloud.firestore_admin_v1 import FirestoreAdminClient
from google.cloud.firestore_admin_v1 import types
from google.iam.v1 import iam_policy_pb2
from google.iam.v1 import policy_pb2
from google.type import expr_pb2


def create_user_creds(project_id: str, database_id: str, user_name: str):
  """Provision new user credentials using the FirestoreAdminClient."""
  client = FirestoreAdminClient()
  request = types.CreateUserCredsRequest(
      parent=f'projects/{project_id}/databases/{database_id}',
      user_creds_id=user_name,
  )
  response = client.create_user_creds(request)
  return response


def update_iam_policy_for_user_creds(
    project_id: str, database_id: str, user_name: str, user_creds
):
  """Update the IAM policy using the Resource Manager ProjectsClient."""
  client = resourcemanager_v3.ProjectsClient()
  request = iam_policy_pb2.GetIamPolicyRequest()
  request.resource = f'projects/{project_id}'
  request.options.requested_policy_version = 3

  # Get the current IAM policy
  current_policy = client.get_iam_policy(request)

  # Construct an updated IAM policy with an additional binding
  # for the user credentials.
  updated_policy = policy_pb2.Policy()
  binding = policy_pb2.Binding()
  iam_condition = expr_pb2.Expr()

  iam_condition.title = f'Conditional IAM binding for {user_name}'
  iam_condition.expression = (
      f'resource.name == "projects/{project_id}/databases/{database_id}"'
  )

  binding.role = 'roles/datastore.user'
  binding.condition.CopyFrom(iam_condition)
  binding.members.append(user_creds.resource_identity.principal)
  updated_policy.bindings.append(binding)

  # Update the policy
  updated_policy.MergeFrom(current_policy)
  set_policy_request = iam_policy_pb2.SetIamPolicyRequest()
  set_policy_request.resource = f'projects/{project_id}'
  set_policy_request.policy.CopyFrom(updated_policy)

  final_policy = client.set_iam_policy(set_policy_request)
  print(f'Policy updated successfully {final_policy}')


def provision_firestore_user_creds_and_iam(
    project_id: str, database_id: str, user_name: str
):
  """Provision user credentials and configure an IAM policy."""
  user_creds = create_user_creds(project_id, database_id, user_name)

  # Note the password returned in the UserCreds proto - it cannot be
  # retrieved again after the initial call to the create_user_creds API.
  print(f'Created credentials for username: {user_name}')
  print(f'IAM principal: {user_creds.resource_identity.principal}')
  print(f'Password: [{user_creds.secure_password}]')

  # Provision an IAM binding for the principal associated with
  # these user credentials.
  update_iam_policy_for_user_creds(
      project_id, database_id, user_name, user_creds
  )

  # Emit the password again
  print(
      f'Successfully configured IAM policy for database: {database_id},'
      f' username: {user_name}'
  )
  print(f'Please make a note of the password: [{user_creds.secure_password}]')

Use a seguinte string de ligação para estabelecer ligação à sua base de dados com SCRAM:

mongodb://USERNAME:PASSWORD@UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&authMechanism=SCRAM-SHA-256&tls=true&retryWrites=false

Substitua o seguinte:

  • USERNAME: o nome de utilizador.
  • PASSWORD: a palavra-passe que gerou para este utilizador.
  • UID: o UID da base de dados.
  • LOCATION: a localização da base de dados.
  • DATABASE_ID: o ID da base de dados.

Associe-se à biblioteca de autenticação Google

O seguinte exemplo de código regista um controlador de callback OIDC que usa a Google Cloud biblioteca OAuth padrão.

Esta biblioteca permite-lhe usar vários tipos diferentes de autenticação (Credenciais padrão da aplicação, Workload Identity Federation).

Isto requer adicionar a biblioteca de autenticação como uma dependência:

// Maven
<dependency>
  <groupId>com.google.auth</groupId>
  <artifactId>google-auth-library-oauth2-http</artifactId>
  <version>1.19.0</version>
</dependency>

// Gradle
implementation 'com.google.auth:google-auth-library-oauth2-http:1.19.0'

O seguinte exemplo de código demonstra como estabelecer ligação:

val db = MongoClients.create(
    clientSettings(
      "DATABASE_UID",
      "LOCATION"
    ).build()
  ).getDatabase("DATABASE_ID")


/**
 * Creates a connection to a Firestore with MongoDB Compatibility database.
 * @param databaseUid The uid of the database to connect to as a string. For example: f116f93a-519c-208a-9a72-3ef6c9a1f081
 * @param locationId The location of the database to connect to, for example: nam5, us-central1, us-east4 etc...
 * @param environment Determines whether to try and fetch an authentication credential from the
 * Compute Engine VM metadata service or whether to call gcloud.
 */
private static MongoClientSettings.Builder clientSettings(
  String databaseUid: String
  String locationId:String
): MongoClientSettings.Builder {
  MongoCredential credential =
    MongoCredential.createOidcCredential(null)
      .withMechanismProperty(
        MongoCredential.OIDC_CALLBACK_KEY,
        new MongoCredential.OidcCallback() {
          @Override
          MongoCredential.OidcCallbackResult onRequest(
MongoCredential.OidcCallbackContext context) {
     // Customize this credential builder for additional credential types.
     GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
            return new MongoCredential.OidcCallbackResult(
         credentials.getAccessToken().getTokenValue(),
         Duration.between(Instant.now(),
credentials.getAccessToken().getExpirationTime().toInstant()));
          }
        },
      );
  return MongoClientSettings.builder()
    .hosts(listOf(ServerAddress(
        "$databaseUid.$locationId.firestore.goog", 443)))
    .credential(credential)
    .applyToClusterSettings(builder ->
         builder.mode(ClusterConnectionMode.LOAD_BALANCED))
    ).applyToSslSettings(ssl -> ssl.enabled(true)).retryWrites(false);
}

Substitua o seguinte:

  • DATABASE_UID: o nome do seu projeto.
  • LOCATION: a localização da sua base de dados.
  • DATABASE_ID o ID da base de dados.

Estabeleça ligação a partir de um Google Cloud ambiente de computação

Esta secção descreve a ligação ao Firestore com compatibilidade com o MongoDB a partir de um Google Cloud ambiente de computação, como o Compute Engine ou um serviço do Cloud Run ou uma tarefa.

Ligue a partir de uma VM do Compute Engine

Pode autenticar e estabelecer ligação à sua base de dados através de uma conta de serviço do Compute Engine. Para o fazer, crie uma política de IAM para o Google Cloud projeto que contém a sua base de dados.

Antes de começar

Configure uma conta de serviço gerida pelo utilizador para a sua VM:

Consulte as instruções nas secções Configurar credenciais para concluir a configuração da política IAM para a sua conta de serviço do Compute Engine.

Estabeleça ligação a partir do Cloud Run

Pode autenticar e estabelecer ligação à sua base de dados através de uma conta de serviço do Cloud Run. Para o fazer, crie uma política de IAM para o Google Cloud projeto que contém a sua base de dados.

Antes de começar

Consulte as instruções nas secções Configurar credenciais para concluir a configuração da política do IAM para a conta de serviço do Cloud Run.

Configure as credenciais

Para conceder à conta de serviço a função roles/datastore.user para leitura e gravação no Firestore, execute o seguinte comando:

gcloud projects add-iam-policy-binding PROJECT_NAME --member="SERVICE_ACCOUNT_EMAIL" --role=roles/datastore.user

Substitua o seguinte:

  • PROJECT_NAME: o nome do seu projeto.
  • SERVICE_ACCOUNT_EMAIL: o endereço de email da conta de serviço que criou.

Construa a string de ligação

Use o seguinte formato para criar a string de ligação:

mongodb://DATABASE_UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&tls=true&retryWrites=false&authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:FIRESTORE

Substitua o seguinte:

  • DATABASE_UID: o nome do seu projeto.
  • LOCATION: a localização da sua base de dados.
  • DATABASE_ID o ID da base de dados.

Para mais informações sobre como obter o UID e a localização, consulte o artigo Obtenha a string de ligação.

Estabeleça ligação com uma chave de acesso temporária

Pode usar um Google Cloud token de acesso temporário para executar ferramentas de diagnóstico como o mongosh. Pode usar gcloud auth print-access-token para fazer a autenticação com um token de acesso de curto prazo. Este token é válido durante uma hora.

Por exemplo, use o seguinte comando para se ligar à sua base de dados com o mongosh:

mongosh --tls \
      --username access_token --password $(gcloud auth print-access-token) \
      'mongodb://UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&authMechanism=PLAIN&authSource=$external&retryWrites=false'

Substitua o seguinte:

  • DATABASE_UID: o UID da base de dados
  • LOCATION: a localização da base de dados
  • DATABASE_ID: um ID da base de dados