المصادقة والربط بقاعدة بيانات

متطلبات الاتصال

في ما يلي المتطلبات اللازمة لعملاء Cloud Firestore:

  • يجب أن تتصل برامج التشغيل في وضع load balanced. ويمنع ذلك برامج التشغيل من محاولة فهم البنية الدقيقة للخادم الذي تتصل به.
  • يجب أن تتصل برامج التشغيل مع تفعيل طبقة المقابس الآمنة (SSL).
  • يجب أن توقف برامج التشغيل عمليات الكتابة القابلة لإعادة المحاولة. Cloud Firestore لا يتيح عمليات الكتابة القابلة لإعادة المحاولة. لست بحاجة إلى إيقاف عمليات القراءة القابلة لإعادة المحاولة لأنّها متاحة.

استرداد سلسلة الاتصال

تعتمد سلسلة اتصال قاعدة البيانات على المعرّف الفريد لقاعدة البيانات وموقعها الجغرافي وآلية المصادقة. توضّح التعليمات التالية كيفية إنشاء سلسلة الاتصال.

تعتمد سلسلة الاتصال الدقيقة على آلية المصادقة، ولكنّ سلسلة الاتصال الأساسية تستخدم التنسيق التالي:

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 لاسترداد المعرّف الفريد ومعلومات الموقع الجغرافي:

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

استبدِل DATABASE_ID برقم تعريف قاعدة البيانات.

يتضمّن الناتج الموقع الجغرافي والمعرّف الفريد لقاعدة البيانات. استخدِم هذه المعلومات لإنشاء سلسلة الاتصال الأساسية.

استخدِم سلسلة الاتصال الأساسية وإحدى الطرق التالية للمصادقة والاتصال بقاعدة البيانات:

الاتصال باستخدام اسم المستخدم وكلمة المرور (SCRAM)

اتّبِع الخطوات التالية لإنشاء بيانات اعتماد مستخدم لقاعدة البيانات والاتصال بها.

قبل البدء

للحصول على الأذونات اللازمة لإنشاء مستخدم، اطلب من المشرف أن يمنحك userCredsAdmin (roles/datastore.userCredsAdmin) دور إدارة الهوية وإمكانية الوصول (IAM) على قاعدة البيانات. لمزيد من المعلومات عن منح الأدوار، يُرجى الاطّلاع على إدارة إمكانية الوصول إلى المشاريع والمجلدات والمؤسسات.

قد تتمكّن أيضًا من الحصول على الأذونات المطلوبة من خلال الأدوار المخصّصة أو الأدوار الأخرى المحدّدة مسبقًا.

إنشاء مستخدم والاتصال بقاعدة بيانات

لإنشاء مستخدم لقاعدة بيانات Cloud Firestore، استخدِم إحدى الطريقتَين التاليتَين:

وحدة تحكُّم Firebase
  1. في وحدة تحكّم Firebase، انتقِل إلى صفحة قاعدة بيانات Firestore.

    الانتقال إلى "قاعدة بيانات Firestore"

  2. اختَر قاعدة بيانات من قائمة قواعد البيانات.
  3. في قائمة التنقّل، انقر على الأمان.
  4. انقر على إضافة مستخدم.
  5. أدخِل اسم مستخدم.
  6. اختَر دورًا للمستخدم الجديد.
  7. انقر على إضافة مستخدم.
  8. سيتم عرض كلمة مرور المستخدم الجديد في مربّع حوار التأكيد.

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"'
    استبدِل ما يلي:
Java

يقدّم هذا القسم مثالاً على الرمز البرمجي لإنشاء بيانات اعتماد المستخدم وضبط سياسة إدارة الهوية وإمكانية الوصول (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);
    }
  }
}
Python

يقدّم هذا القسم مثالاً على الرمز البرمجي لإنشاء بيانات اعتماد المستخدم وضبط سياسة إدارة الهوية وإمكانية الوصول (IAM) باستخدام مكتبات عملاء الإدارة في Python. يستخدِم المثال مكتبة Google Cloud Firestore API client library لإنشاء اسم مستخدم وكلمة مرور، و مكتبة Google Cloud Iam API client library ومكتبة Google Cloud Resource Manager API client library لضبط إدارة الهوية وإمكانية الوصول (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: المعرّف الفريد لقاعدة البيانات. مثلاً: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: موقع قاعدة البيانات الجغرافي.
  • DATABASE_ID: رقم تعريف قاعدة البيانات.

الاتصال باستخدام مكتبة Google Auth

تسجِّل عينة الرمز البرمجي التالي معالج رد الاتصال بـ OIDC ويستخدِم Google Cloud مكتبة OAuth العادية.

تتيح لك هذه المكتبة استخدام عدد من أنواع المصادقة المختلفة (بيانات الاعتماد التلقائية للتطبيق، واتحاد هوية Workload Identity).

يتطلّب ذلك إضافة مكتبة المصادقة كإحدى التبعيات:

// 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: المعرّف الفريد لقاعدة البيانات. مثلاً: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: موقع قاعدة البيانات الجغرافي.
  • DATABASE_ID رقم تعريف قاعدة البيانات.

الاتصال من بيئة حوسبة Google Cloud

يصف هذا القسم كيفية الاتصال بـ Cloud Firestore من بيئة حوسبة Google Cloud ، مثل Compute Engine أو خدمة Cloud Run أو مهمة.

الاتصال من جهاز Compute Engine VM

يمكنك المصادقة والاتصال بقاعدة البيانات باستخدام حساب خدمة 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="serviceAccount: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: المعرّف الفريد لقاعدة البيانات. مثلاً: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: موقع قاعدة البيانات الجغرافي.
  • DATABASE_ID رقم تعريف قاعدة البيانات.

لمزيد من المعلومات عن استرداد المعرّف الفريد والموقع الجغرافي، يُرجى الاطّلاع على استرداد سلسلة الاتصال.

الاتصال باستخدام رمز الدخول المؤقت

يمكنك استخدام رمز دخول مؤقت 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: المعرّف الفريد لقاعدة البيانات. مثلاً: f116f93a-519c-208a-9a72-3ef6c9a1f081
  • LOCATION: موقع قاعدة البيانات الجغرافي
  • DATABASE_ID: رقم تعريف قاعدة البيانات