僅適用於 Cloud Firestore Enterprise 版。 |
連線需求
與 MongoDB 相容的 Cloud Firestore 用戶端必須符合下列條件:
- 駕駛人必須以
load balanced
模式連線。 這樣一來,驅動程式就不會嘗試瞭解所連線的確切伺服器拓撲。 - 驅動程式必須啟用 SSL 才能連線。
- 驅動程式必須停用可重試的寫入作業。 與 MongoDB 相容的 Cloud Firestore 不支援可重試的寫入作業。您不需要停用可重試的讀取作業,因為系統支援這類作業。
擷取連線字串
資料庫連線字串取決於資料庫的 UID、資料庫位置和驗證機制。下列操作說明將說明如何形成連線字串。
確切的連線字串取決於驗證機制,但基本連線字串採用下列格式:
mongodb://UID.LOCATION.firestore.goog:443/DATABASE_ID?loadBalanced=true&tls=true&retryWrites=false
您可以透過下列其中一種方式取得基本連線字串:
Firebase 控制台
-
前往 Firebase 控制台的「Firestore Database」頁面。
- 按一下要驗證的資料庫。
- 在「Explorer」面板中,按一下 「View more」。
- 選取「使用 MongoDB 工具連結」。
- 複製連線字串。
gcloud
使用 gcloud firestore database describe
擷取 UID 和位置資訊:
gcloud firestore databases describe \ --database=DATABASE_ID \ --format='yaml(locationId, uid)'
將 DATABASE_ID 替換為資料庫 ID。
輸出內容會包含資料庫的位置和 UID。使用這項資訊建構基本連線字串。
使用基本連線字串和下列其中一種方法,驗證並連線至資料庫:
使用使用者名稱和密碼 (SCRAM) 連線
請按照下列步驟建立資料庫的使用者憑證,並連線至資料庫。
事前準備
如要取得建立使用者所需的權限,請要求管理員為您授予資料庫的 userCredsAdmin (roles/datastore.userCredsAdmin
) IAM 角色。如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和機構的存取權」一文。
建立使用者並連線至資料庫
如要為與 MongoDB 相容的 Cloud Firestore 資料庫建立使用者,請使用下列其中一種方法:
Google Cloud 控制台
-
前往 Google Cloud 控制台的「資料庫」頁面。
- 從資料庫清單中選取資料庫。
- 按一下導覽選單中的「Auth」(驗證)。
- 按一下「新增使用者」。
- 輸入使用者名稱。
- 為新使用者選取角色。
-
按一下「新增」。
確認對話方塊會顯示新使用者的密碼。
gcloud CLI
-
如要使用 SCRAM 驗證,請先建立使用者憑證。使用
gcloud firestore user-creds
指令: 取代下列項目:gcloud firestore user-creds create USERNAME --database=DATABASE_ID
- USERNAME:要建立的使用者名稱。
- DATABASE_ID:資料庫 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
-
根據預設,這個新使用者憑證沒有任何權限。如要取得資料庫的讀寫權限,請為這個特定資料庫新增
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"'
- PROJECT_NAME:專案名稱。
- PROJECT_NUMBER:專案編號。
- DATABASE_ID:資料庫 ID。
- USERNAME:先前建立的使用者名稱。
- CONDITION_TITLE:此條件的標題。這項條件會限制存取權,僅限於這個資料庫。
Java
本節提供程式碼範例,說明如何使用 Java 管理用戶端程式庫建立使用者憑證,以及設定 IAM 政策。這個範例會使用 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
本節提供程式碼範例,說明如何使用 Python 管理用戶端程式庫建立使用者憑證,以及設定 IAM 政策。這個範例使用 Google Cloud Firestore API 用戶端程式庫建立使用者名稱和密碼,並使用 Google Cloud Iam API 用戶端程式庫和 Google Cloud Resource Manager API 用戶端程式庫設定 IAM。
您可以使用 pip 工具安裝必要的 Python 程式庫:
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:資料庫 ID。
連結 Google 驗證程式庫
下列程式碼範例會註冊 OIDC 回呼處理常式,並使用Google Cloud 標準 OAuth 程式庫。
這個程式庫可讓您使用多種驗證類型 (應用程式預設憑證、Workload Identity Federation)。
這需要將驗證程式庫新增為依附元件:
// 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 資料庫 ID。
從 Google Cloud 計算環境連線
本節說明如何從Google Cloud運算環境 (例如 Compute Engine 或 Cloud Run 服務/工作) 連線至與 MongoDB 相容的 Cloud Firestore。
透過 Compute Engine VM 連線
您可以使用 Compute Engine 服務帳戶驗證及連線至資料庫。如要這麼做,請為包含資料庫的 Google Cloud 專案建立 IAM 政策。
事前準備
為 VM 設定使用者代管的服務帳戶:
- 如要在建立 VM 時設定服務帳戶,請參閱「建立使用使用者管理服務帳戶的 VM」。
- 如要在現有 VM 上設定服務帳戶,請參閱「變更附加的服務帳戶」。
請參閱「設定憑證」一節中的操作說明,為 Compute Engine 服務帳戶完成 IAM 政策設定。
從「Cloud Run」連線
您可以使用 Cloud Run 服務帳戶驗證及連線至資料庫。如要這麼做,請為包含資料庫的 Google Cloud 專案建立 IAM 政策。
事前準備
- 如要為 Cloud Run 設定服務帳戶,請參閱「設定服務身分」。
- 如要判斷已與 Cloud Run 服務建立關聯的服務帳戶,請參閱 gcloud run services describe
請參閱「設定憑證」一節中的操作說明,為 Cloud Run 服務帳戶完成 IAM 政策設定。
設定憑證
如要授予服務帳戶 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 資料庫 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:資料庫 ID