使用默认凭据访问 Google 表格

Using default credentials for accessing Google Sheets

我在 Google 表格上有一些数据。我正在使用 Sheets API for Node.js 访问此数据。对于身份验证,我使用服务帐户 JSON 生成 JWTClient。

我可以访问工作表中的数据 api 并且一切正常。代码托管在 Google App Engine Flexible environment 上。它适用于本地主机和 GAE。

唯一的问题是我需要提供服务帐户密钥 json 进行身份验证。这在本地环境中很好,但在 App Engine 上它为服务帐户提供了一个 default credential(我使用的是相同的服务帐户)。所以我认为我不应该手动提供凭据并让 GAE 处理服务器上的凭据。

但它不会自动进行身份验证,仍然是一个身份验证参数。

这是我目前对工作表的实现 api -

const { promisify } = require('util');
const google = require('googleapis');
const auth = require('./auth');
const credentials = require('../configs/credentials');

const sheets = google.sheets('v4');
const getSheetValuesAsync = promisify(sheets.spreadsheets.values.get);
//region private
function readSheet(params) {
  return getSheetValuesAsync(params);
}
//endregion private

//region public
async function get(sheetConfigName) {
  const sheetConfig = credentials.sheets[sheetConfigName];
  //This is theJWTClient which authenticates the api request currently.
  //I want to remove this
  const authClient = await auth.authorizeWithServiceAccount('serviceAccountName', [
    'https://www.googleapis.com/auth/spreadsheets.readonly'
  ]);
  console.log('Client received');
  let params = {
    auth: authClient, //I tried removing this parameter, but it didn't work
    spreadsheetId: sheetConfig.id,
    range: 'A:M'
  };
  let data = await readSheet(params);
  return data;
}
//endregion public
module.exports = {
  get: get
};

我得到的错误如下:-

{
  code:403,
  message: 'The request is missing a valid API key.
}

我已经为本地环境设置了 GOOGLE_APPLICATION_CREDENTIALS 环境变量,它已经适用于 google-cloud APIs,但不适用于工作表。

那么 Application Default Credentials 是仅用于 google-cloud APIs 还是可以与 Sheets API 或任何其他 Drive APIs 一起使用?如果它也可以与驱动器 APIs 一起使用,如何实现?

如果您想使用 Google 表格 API,您需要提供一个 OAuth 服务帐户,如 documentation 中所示。默认服务帐户主要用于从 GCP (Google Cloud Platform) 中提取数据时使用。因此,您的计算引擎可以访问您的云数据存储,或者如果您的 App 引擎可以访问您的云存储。

默认服务帐户没有客户端密码 JSON,表格 API 需要客户端密码。

或者,如果您想使用 Google Sheets REST API.

,您可以对 public 文档使用 API 密钥

Google 云服务帐户旨在访问 Cloud APIs,不能被授予 Sheets API.

的适当范围

自从 App Engine Flexible 应用程序 运行 在 Compute Engine VM 上,您可以通过查询元数据服务器来获取默认服务帐户的令牌,如下所示:

> curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"

但是,当调用提供该标记的工作表 API 时,会出现以下错误:

{
  "error": {
    "code": 403,
    "message": "Request had insufficient authentication scopes.",
    "status": "PERMISSION_DENIED"
  }
}

我相信您需要为您的用例使用 API 键。

在 Google 的 Node.js 客户端包 (28.x) 的最新更新中,他们有一种无需第二个包即可获取 authClient 的新方法。这是如何完成的 -

const { google } = require('googleapis');
  const authClient = await google.auth.getClient({
  credentials: credentials,
  scopes: scopes
});

credentials 只是服务帐户 JSON 对象。最好的部分是,如果您不提供 属性,它将检查 GOOGLE_APPLICATION_CREDENTIALS 环境变量,该变量将具有服务帐户密钥 JSON 的绝对路径并自动考虑它用于身份验证。
您可以使用为 google 工作表 API 生成的 authClient 通过以下任一方式设置 auth 参数 -

首先是当您想为不同的 API 调用提供不同的身份验证时。

const { google } = require('googleapis');
const sheets = google.sheets('v4');
sheets.spreadsheets.values.getAsync = promisify(sheets.spreadsheets.values.get);
sheets.spreadsheets.values.getAsync({
    auth: authClient,
    spreadsheetId: spreadsheetId,
    range: range
  });

或者您可以直接向工作表对象提供授权。该对象上的所有 API 调用都将使用相同的 authClient,并且不需要 auth 参数。

const sheets = google.sheets({version:'v4',auth:authClient);

最好的方法是将所有 Google API 调用的身份验证设置为默认值,这样您就不必将 authClient 传递给任何工作表对象或 API 来电。

google.options({
  auth: authClient
});

如果您计划使用不同的服务帐户不同的 API。

对于本地测试,您始终可以设置环境路径,这样您实际上不必将服务帐户传递给 google.auth 对象。这是我的做法

let resolve = require('path').resolve;
if (process.env.NODE_ENV === 'production') {
  //Set config based on production environment. It won't be set in local environment, unless you specially set it.
} else if (!process.env.GOOGLE_APPLICATION_CREDENTIALS) {
  process.env.GOOGLE_APPLICATION_CREDENTIALS = resolve(
      './relative/path/to/the/json/key.json'
  ); //resolve will just convert relative path to the absolute path.
}