CLOUD_SDK_CREDENTIALS_WARNING 我们建议大多数服务器应用程序改用服务帐户

CLOUD_SDK_CREDENTIALS_WARNING We recommend that most server applications use service accounts instead

上下文:我刚刚学会了从 FireStore 仪表板获取(下载)数据的技巧。显然,在浏览器上打开 Google 仪表板并亲眼看到自己的 Google 仪表板要容易得多。尽管如此,出于个人原因,在我公司,操作员无法查看第三个仪表板。他们只能看到内部仪表板。我正在尝试一些解决方法,我可以 get/download 用于填写仪表板的相同数据并将其导入到我们基于 Dynatrace/ELK 的内部解决方案中。

出于学习目的,为了下载Google仪表板数据我关注了:

1 - 使用 gcloud

获取 ACCESS_TOKEN
C:\Program Files (x86)\Google\Cloud SDK>gcloud auth application-default print-access-token
C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\bin\..\lib\third_party\google\auth\_default.py:69: UserWarning: Your application has authenticated using end user credentials from Google Cloud SDK. We recommend that most server applications use service accounts instead. If your application continues to use end user credentials from Cloud SDK, you might receive a "quota exceeded" or "API not enabled" error. For more information about service accounts, see https://cloud.google.com/docs/authentication/
  warnings.warn(_CLOUD_SDK_CREDENTIALS_WARNING)
ya29. ... ACCESS-TOKEN ...7hu

2 - 使用上述 ACCESS_TOKEN 获取仪表板数据,如:

curl --location --request GET 'https://monitoring.googleapis.com/v3/projects/firetestjimis/timeSeries?filter=metric.type%20%3D%20%22firestore.googleapis.com%2Fdocument%2Fread_count%22&interval.endTime=2020-05-07T15:01:23.045123456Z&interval.startTime=2020-05-05T15:01:23.045123456Z' --header 'Authorization: Bearer ya29...ACCESS-TOKEN 7hu'

显然,这只是一个示例,说明如何获取满足过滤条件的连接数。我可以根据 Google Cloud Metrics and Google Cloud API v3

继续搜索调整 API 和过滤器

这次从 API 版本 1 获取仪表板元数据的另一个例子是

curl --location --request GET 'https://monitoring.googleapis.com/v1/projects/firetestjimis/dashboards' --header 'Authorization: Bearer ya29... ACCESS-TOKEN ...7hu'

从 gcloud 获取访问令牌时的警告鼓励看到 Authentication guidance 我做到了。好吧,它没有解释如何修复此警告,也没有解释为什么 "If your application continues to use end user credentials from Cloud SDK, you might receive a "quota exceeded" 或 "API not enabled" 错误"。我可以看到我从 Dashboard 获取数据的技巧正在发挥作用,但似乎我依赖于一种奇怪的方式来获取 ACCESS-TOKEN。

所以我的直接问题是:手动获取访问令牌并在 curl/postman 中使用它以避免此类警告的适当步骤是什么?

在我看来,基于此 根本原因是“...此错误消息意味着您使用的是用户帐户,而不是服务帐户...”那么如何我可以修好吗?我必须创建一个服务帐户吗?如果是这样,如何?在这个已接受的答案的末尾,我读到“...要使用真正的应用程序默认值,您可以使用 gcloud auth application-default login...”这正是我使用 gcloud 登录的方式:运行 gcloud auth应用程序默认登录,当打开 Google SingleSignOn 我选择我的电子邮件,这是我在 Firebase 帐户中注册的同一用户。答案还提到“...关联特定服务帐户的方法是 gcloud auth activate-service-account --key-file ...”我想试一试,但哪个密钥文件是 he/she 在说什么?

万一它是相关的,在我的例子中,我只在 Firebase 项目下使用 FireStore(我没有使用除 FireStore 之外的任何其他东西)。

*** 在约翰回答后编辑

我们即将将该项目投入生产。

1 - 我们的移动应用程序将通过 post 将其发送到我们的内部微服务来创建汇款。这样的 post 请求将 return 从我们的内部 NodeJs 服务器生成的 CustomToken。

2 - 我们的内部微服务会将此类传输复制到 Firestore 并相应地更新其在 Firestore 上的状态。

3 - 代替我们的移动应用轮询或监听我们的内部微服务来获取状态,它将监听 Firestore 以从相应文档获取状态。为了收听,它将在步骤 1 中使用来自 post 的 CustomToken returned。我们公司只想利用来自 Google Firestore 的实时数据库功能来进行此项目(反应式方法) ).

将我所做的与您的声明进行比较时,您是否看到了任何考虑:"Google prefers in most cases that you authorize using a service account"?

CustomToken 是使用此 NodeJs 服务器在内部创建的,并取决于从预期用户提取的 uid authentication/users from Google Firebase

    const admin = require('firebase-admin');

    exports.serviceAccount = {
      "type": "service_account",
      "project_id": "firetestjimis",
      "private_key_id": "ecfc6 ... fd05923",
      "private_key": "-----BEGIN PRIVATE KEY-----\nMIIE .... 5EKvQ==\n-----END PRIVATE KEY-----\n",
      "client_email": "firebase-adminsdk-fg6p9@firetestjimis.iam.gserviceaccount.com",
      "client_id": "102422819688924138150",
      "auth_uri": "https://accounts.google.com/o/oauth2/auth",
      "token_uri": "https://oauth2.googleapis.com/token",
      "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
      "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fg6p9%40firetestjimis.iam.gserviceaccount.com"
    }

     admin.initializeApp({
       credential: admin.credential.cert(exports.serviceAccount)
    });


var uid = "NS .... Ro2"; //copied from https://console.firebase.google.com/project/firetestjimis/authentication/users
var claim = {
  control: true
};
admin.auth().createCustomToken(uid)
  .then(function (customToken) {
    console.log(customToken)
  })
  .catch(function (error) {
    console.log("Error creating custom token:", error);
  });

我们的手机(Angular 中的示例,但 IOS 和 Android 的想法相同)有 SERVICE_ACCOUNT_JSON_FILE 我这样下载:

environment.ts:

export const environment = {
  production: false,
  firebaseConfig: {
    apiKey: "AIzaSy ... 3DCGihK3xs",
    authDomain: "firetestjimis.firebaseapp.com",
    databaseURL: "https://firetestjimis.firebaseio.com",
    projectId: "firetestjimis",
    storageBucket: "firetestjimis.appspot.com",
    messagingSenderId: "795318872350",
    appId: "1:7953 ... 32b26fb53dc810f"
  }
};

app.component.ts

  public transfers: Observable<any[]>;

  transferCollectionRef: AngularFirestoreCollection<any>;

  constructor(public auth: AngularFireAuth, public db: AngularFirestore) {
    this.listenSingleTransferWithToken();
  }

  async listenSingleTransferWithToken() {
    await this.auth.signInWithCustomToken("eyJh ### CUSTOMTOKEN GENERATED FROM INTERNAL NODEJS SERVER ABOVE ### CVg");
    this.transferCollectionRef = this.db.collection<any>('transfer', ref => ref.where("id", "==", "1"));
    this.transfers = this.transferCollectionRef.snapshotChanges().map(actions => {
      return actions.map(action => {
        const data = action.payload.doc.data();
        const id = action.payload.doc.id;
        return { id, ...data };
      });
    });
  }
}

我了解 CustomToken 的创建及其在我们手机上的使用完全依赖于服务帐户。我对吗?我是否错过了一些概念并且我在幕后使用 USER CREDENTIAL 并且在 DEV 环境中正常工作的东西在生产时会弹出一些惊喜?显然这个问题都来自我的免费帐户,但在生产中它将是付费帐户,但代码和步骤将与这里完全相同。

因此,授权令牌是根据您的 gcloud init 授权生成的,它是最终用户凭据。这就是为什么你收到那个警告。因为您已使用手动登录凭据生成令牌。

首选的身份验证方式是使用服务帐户(此处的文档:https://cloud.google.com/iam/docs/service-accounts)进行身份验证。该文档还将引导您完成创建服务帐户的过程。如果您使用它与 Firestore 通信,您的服务帐户将需要适当的 Firestore 角色权限。不要混淆你,但 IAM 中的角色是 datastore 尽管他们申请 Firestore。

此页面:https://cloud.google.com/firestore/docs/security/iam 列出了 roles/permissions 您的服务帐户需要哪些才能使用 Firestore 执行各种操作。

现在,综上所述,它所谈论的密钥文件是您可以在创建服务帐户时下载的服务帐户密钥。最简单的方法是通过 GCP 项目中的控制台来完成,因为当您创建服务帐户时,有一个方便的按钮可以创建密钥,并将其下载到您的本地计算机。

CLI 使用两种类型的凭据:

  • 用户凭据
  • 服务帐户

Google 在大多数情况下更喜欢您使用服务帐户进行授权。但是,某些服务需要用户凭据(通常是非 Google 云平台服务)。请参阅您使用的每项服务的文档。

执行以下命令。这将显示您正在使用的凭据:

gcloud auth list

要将 CLI 配置为使用服务帐户,请执行此命令:

gcloud auth activate-service-account <SERVICE_ACCOUNT_EMAIL_ADDRESS> --key-file=<SERVICE_ACCOUNT_JSON_FILE>

我写了一篇更详细解释的文章(以及几篇关于服务帐户、授权等的附加文章):

Google Cloud – Setting up Gcloud with Service Account Credentials