Eseguire l'autenticazione e connettersi a un database

Requisiti di connessione

Di seguito sono riportati i requisiti per i client Cloud Firestore:

  • I driver devono connettersi in modalità load balanced. In questo modo, i driver non tentano di comprendere la topologia esatta del server a cui si stanno connettendo.
  • I driver devono connettersi con SSL abilitato.
  • I driver devono disabilitare le scritture ripetibili. Cloud Firestore non supporta le scritture ripetibili. Non è necessario disabilitare le letture ripetibili perché sono supportate.

Recuperare la stringa di connessione

La stringa di connessione al database dipende dall'UID del database, dalla posizione del database e dal meccanismo di autenticazione. Le istruzioni riportate di seguito descrivono come viene formata la stringa di connessione.

La stringa di connessione esatta dipende dal meccanismo di autenticazione, ma la stringa di connessione di base utilizza il seguente formato:

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

Puoi ottenere la stringa di connessione di base in uno dei seguenti modi:

Firebase console
  1. Nella console Firebase, vai alla pagina Database Firestore.

    Vai a Database Firestore

  2. Fai clic sul database che vuoi autenticare.
  3. Nel riquadro Explorer, fai clic su Visualizza altro.
  4. Seleziona Connettiti utilizzando gli strumenti MongoDB.
  5. Copia la stringa di connessione.
gcloud

Utilizza gcloud firestore database describe per recuperare l'UID e le informazioni sulla località:

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

Sostituisci DATABASE_ID con l'ID database.

L'output include la località e l'UID del database. Utilizza queste informazioni per creare la stringa di connessione di base.

Utilizza la stringa di connessione di base e uno dei seguenti metodi per autenticare e connetterti al database:

Connettersi con nome utente e password (SCRAM)

Segui questi passaggi per creare le credenziali utente per il database e connetterti al database.

Prima di iniziare

Per ottenere le autorizzazioni necessarie per creare un utente, chiedi all'amministratore di concederti il ruolo IAM userCredsAdmin (roles/datastore.userCredsAdmin) sul database. Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Creare un utente e connettersi a un database

Per creare un utente per il database Cloud Firestore, utilizza uno dei seguenti metodi:

Firebase console
  1. Nella console Firebase, vai alla pagina Database Firestore.

    Vai a Database Firestore

  2. Seleziona un database dall'elenco dei database.
  3. Nel menu di navigazione, fai clic su Sicurezza.
  4. Fai clic su Aggiungi utente.
  5. Inserisci un nome utente.
  6. Seleziona un ruolo per il nuovo utente.
  7. Fai clic su Aggiungi utente.
  8. La password del nuovo utente verrà visualizzata nella finestra di dialogo di conferma.

gcloud CLI
  1. Per eseguire l'autenticazione con SCRAM, devi prima creare le credenziali utente. Utilizza il comando gcloud firestore user-creds:
    gcloud firestore user-creds create USERNAME --database=DATABASE_ID
    Sostituisci quanto segue:
    • USERNAME: il nome utente da creare.
    • DATABASE_ID: l'ID database.

    L'output di questo comando include la password dell'utente.

    L'output è simile al seguente:

    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. Per impostazione predefinita, queste nuove credenziali utente non hanno autorizzazioni. Per l'accesso in lettura e scrittura al database, aggiungi il ruolo roles/datastore.user per questo database specifico:

    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"'
    Sostituisci quanto segue:
Java

Questa sezione fornisce un esempio di codice per la creazione delle credenziali utente e la configurazione della policy IAM utilizzando le librerie client di amministrazione Java. L'esempio utilizza la libreria client di amministrazione di Firestore per la creazione di un nome utente e una password e la libreria Google Cloud Resource Manager per la configurazione di IAM.

Per le build Maven, puoi utilizzare le seguenti coordinate:

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

Esegui il provisioning delle credenziali utente e di una policy 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

Questa sezione fornisce un esempio di codice per la creazione delle credenziali utente e la configurazione della policy IAM utilizzando le librerie client di amministrazione Python. L'esempio utilizza la libreria client dell'API Google Cloud Firestore per la creazione di un nome utente e una password e la libreria client dell'API Google Cloud Iam e la libreria client dell'API Google Cloud Resource Manager per la configurazione di IAM.

Le librerie Python richieste possono essere installate con lo strumento pip:

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

Esegui il provisioning delle credenziali utente e di una policy 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}]')

Utilizza la seguente stringa di connessione per connetterti al database con SCRAM:

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

Sostituisci quanto segue:

  • USERNAME: il nome utente.
  • PASSWORD: la password che hai generato per questo utente.
  • UID: l'UID del database. Ad esempio: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: la località del database.
  • DATABASE_ID: l'ID database.

Connettersi con la libreria di autenticazione di Google

Il seguente esempio di codice registra un gestore callback OIDC utilizzando la Google Cloud libreria OAuth standard.

Questa libreria ti consente di utilizzare diversi tipi di autenticazione (credenziali predefinite dell'applicazione, federazione delle identità per i workload).

Per farlo, devi aggiungere la libreria di autenticazione come dipendenza :

// 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'

Il seguente esempio di codice mostra come connettersi:

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

Sostituisci quanto segue:

  • DATABASE_UID: l'UID del database. Ad esempio: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: la località del database.
  • DATABASE_ID l'ID database.

Connettersi da un ambiente di calcolo Google Cloud

Questa sezione descrive come connettersi a Cloud Firestore da un Google Cloud ambiente di calcolo, ad esempio Compute Engine o un servizio o un job Cloud Run.

Connettersi da una VM Compute Engine

Puoi autenticare e connetterti al database utilizzando un Compute Engine service account. Per farlo, crea una policy IAM per il Google Cloud progetto che contiene il database.

Prima di iniziare

Configura un service account gestito dall'utente per la VM:

Consulta le istruzioni nelle sezioni Configurare le credenziali per completare la configurazione della policy IAM per il Compute Engine service account.

Connettersi da Cloud Run

Puoi autenticare e connetterti al database utilizzando un Cloud Run service account. Per farlo, crea una policy IAM per il Google Cloud progetto che contiene il database.

Prima di iniziare

Consulta le istruzioni nelle sezioni Configurare le credenziali per completare la configurazione della policy IAM per il Cloud Run service account.

Configurare le credenziali

Per concedere al service account il ruolo roles/datastore.user per la lettura e la scrittura in Cloud Firestore, esegui il seguente comando:

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

Sostituisci quanto segue:

  • PROJECT_NAME: il nome del progetto.
  • SERVICE_ACCOUNT_EMAIL: l'indirizzo email del service account che hai creato.

Creare la stringa di connessione

Utilizza il seguente formato per creare la stringa di connessione:

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

Sostituisci quanto segue:

  • DATABASE_UID: l'UID del database. Ad esempio: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: la località del database.
  • DATABASE_ID l'ID database.

Per saperne di più su come recuperare l'UID e la località, consulta Recuperare la stringa di connessione.

Connettersi con un token di accesso temporaneo

Puoi utilizzare un token di accesso temporaneo Google Cloud per eseguire strumenti di diagnostica come mongosh. Puoi utilizzare gcloud auth print-access-token per eseguire l'autenticazione con un token di accesso a breve termine. Questo token è valido per un'ora.

Ad esempio, utilizza il seguente comando per connetterti al database con 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'

Sostituisci quanto segue:

  • DATABASE_UID: l'UID del database. Ad esempio: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: la località del database
  • DATABASE_ID: un ID database