Аутентификация и подключение к базе данных

Относится только к версии Cloud Firestore Enterprise.

Требования к подключению

Для совместимости Cloud Firestore с клиентами MongoDB требуется следующее:

  • Драйверы должны подключаться в режиме load balanced . Это не позволяет драйверам пытаться определить точную топологию сервера, к которому они подключаются.
  • Драйверы должны подключаться с включенным протоколом SSL.
  • Драйверы должны отключать повторные записи. Cloud Firestore, совместимый с MongoDB, не поддерживает повторные записи. Вам не нужно отключать повторные чтения, так как они поддерживаются.

Получить строку подключения

Строка подключения к базе данных зависит от UID базы данных, её расположения и механизма аутентификации. Ниже описан порядок формирования строки подключения.

Точная строка подключения зависит от механизма аутентификации, но базовая строка подключения использует следующий формат:

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

Базовую строку подключения можно получить одним из следующих способов:

Консоль Firebase
  1. В консоли Firebase перейдите на страницу базы данных Firestore .

    Перейти к базе данных Firestore

  2. Щелкните базу данных, которую вы хотите аутентифицировать.
  3. На панели проводника нажмите Просмотреть больше .
  4. Выберите Подключиться с помощью инструментов MongoDB .
  5. Скопируйте строку подключения.
gcloud

Используйте gcloud firestore database describe для получения информации об UID и местоположении:

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

Замените DATABASE_ID на идентификатор базы данных.

Вывод включает местоположение и уникальный идентификатор базы данных. Используйте эту информацию для построения базовой строки подключения.

Используйте базовую строку подключения и один из следующих методов для аутентификации и подключения к вашей базе данных:

Подключитесь с именем пользователя и паролем (SCRAM)

Выполните следующие действия, чтобы создать учетные данные пользователя для вашей базы данных и подключиться к ней.

Прежде чем начать

Чтобы получить разрешения, необходимые для создания пользователя, попросите администратора предоставить вам IAM-роль userCredsAdmin ( roles/datastore.userCredsAdmin ) в вашей базе данных. Подробнее о предоставлении ролей см. в статье Управление доступом к проектам, папкам и организациям .

Вы также можете получить необходимые разрешения с помощью пользовательских ролей или других предопределенных ролей .

Создайте пользователя и подключитесь к базе данных

Чтобы создать пользователя для базы данных Cloud Firestore с совместимостью с MongoDB, используйте один из следующих методов:

Консоль Google Cloud
  1. В консоли Google Cloud перейдите на страницу Базы данных .

    Перейти к базам данных

  2. Выберите базу данных из списка баз данных.
  3. В навигационном меню нажмите кнопку «Аутентификация» .
  4. Нажмите Добавить пользователя .
  5. Введите имя пользователя .
  6. Выберите роль для нового пользователя.
  7. Нажмите «Добавить» .

    Пароль нового пользователя будет отображен в диалоговом окне подтверждения.

gcloud CLI
  1. Для аутентификации в SCRAM необходимо сначала создать учётные данные пользователя. Используйте команду gcloud firestore user-creds :
    gcloud firestore user-creds create USERNAME --database=DATABASE_ID
    Заменить следующее:
    • USERNAME : имя пользователя, которое необходимо создать.
    • DATABASE_ID : идентификатор базы данных.

    Вывод этой команды включает пароль пользователя.

    Вывод будет выглядеть примерно так:

    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. По умолчанию у этого нового пользователя нет никаких прав. Чтобы получить доступ на чтение и запись в базу данных, добавьте роль roles/datastore.user для этой базы данных:

    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"'
    Заменить следующее:
Ява

В этом разделе представлен пример кода для создания учётных данных пользователя и настройки политики IAM с помощью административных клиентских библиотек Java. В примере используется библиотека Firestore Admin Client для создания имени пользователя и пароля, а также библиотека Google Cloud Resource Manager для настройки IAM.

Для сборок Maven вы можете использовать следующие координаты:

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

Предоставьте учетные данные пользователя и политику 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);
    }
  }
}
Питон

В этом разделе представлен пример кода для создания учётных данных пользователя и настройки политики IAM с помощью административных клиентских библиотек Python. В примере используется клиентская библиотека API Google Cloud Firestore для создания имени пользователя и пароля, а также клиентские библиотеки API Google Cloud Iam и API Google Cloud Resource Manager для настройки IAM.

Необходимые библиотеки Python можно установить с помощью инструмента pip:

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

Предоставьте учетные данные пользователя и политику 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}]')

Для подключения к базе данных с помощью SCRAM используйте следующую строку подключения:

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

Заменить следующее:

  • USERNAME : имя пользователя.
  • PASSWORD : пароль, который вы сгенерировали для этого пользователя.
  • UID : UID базы данных.
  • LOCATION : местоположение базы данных.
  • DATABASE_ID : идентификатор базы данных.

Подключитесь к библиотеке аутентификации Google

Следующий пример кода регистрирует обработчик обратного вызова OIDC, используя стандартную библиотеку OAuth Google Cloud .

Эта библиотека позволяет использовать ряд различных типов аутентификации (учетные данные приложения по умолчанию, объединение удостоверений рабочей нагрузки).

Для этого необходимо добавить библиотеку аутентификации в качестве зависимости :

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

Следующий пример кода демонстрирует, как подключиться:

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

Заменить следующее:

  • DATABASE_UID : название вашего проекта.
  • LOCATION : местоположение вашей базы данных.
  • DATABASE_ID идентификатор базы данных.

Подключение из вычислительной среды Google Cloud

В этом разделе описывается подключение к Cloud Firestore с совместимостью с MongoDB из вычислительной среды Google Cloud , например Compute Engine или службы или задания Cloud Run .

Подключение из виртуальной Compute Engine

Вы можете аутентифицироваться и подключаться к своей базе данных, используя учётную запись сервиса Compute Engine . Для этого создайте IAM-политику для проекта Google Cloud , содержащего вашу базу данных.

Прежде чем начать

Настройте управляемую пользователем учетную запись службы для вашей виртуальной машины:

Инструкции по настройке политики IAM для вашей учетной записи службы Compute Engine см. в разделах «Настройка учетных данных» .

Подключиться из Cloud Run

Вы можете аутентифицироваться и подключаться к своей базе данных, используя учётную запись сервиса Cloud Run . Для этого создайте IAM-политику для проекта Google Cloud , содержащего вашу базу данных.

Прежде чем начать

Инструкции по настройке политики IAM для вашей учетной записи службы Cloud Run см. в разделах «Настройка учетных данных» .

Настроить учетные данные

Чтобы предоставить учетной записи службы роль roles/datastore.user для чтения и записи в Cloud Firestore , выполните следующую команду:

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

Заменить следующее:

  • PROJECT_NAME : название вашего проекта.
  • SERVICE_ACCOUNT_EMAIL : адрес электронной почты для созданной вами учетной записи службы.

Построить строку подключения

Для построения строки подключения используйте следующий формат:

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

Заменить следующее:

  • DATABASE_UID : название вашего проекта.
  • LOCATION : местоположение вашей базы данных.
  • DATABASE_ID идентификатор базы данных.

Дополнительную информацию о получении UID и местоположения см. в разделе Получение строки подключения .

Подключитесь с помощью временного токена доступа

Вы можете использовать временный токен доступа Google Cloud для запуска диагностических инструментов, таких как mongosh . Для аутентификации с помощью краткосрочного токена доступа можно использовать gcloud auth print-access-token . Этот токен действителен в течение одного часа.

Например, используйте следующую команду для подключения к базе данных с помощью 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'

Заменить следующее:

  • DATABASE_UID : UID базы данных
  • LOCATION : местоположение базы данных
  • DATABASE_ID : идентификатор базы данных