使用服务帐户通过 Google API 进行授权

Authorizing with Google APIs using a service account

我正在尝试使用 nodeJS 和服务帐户文件从 google-api 访问一些 google 组。我找不到像这样工作的代码示例。我已经整理了一些似乎可以正常工作的代码,但我一直收到错误 400 - 来自 API 的错误请求,但没有任何线索表明出了什么问题。

我用对了吗类?我可以在这里使用服务帐户吗?我是不是缺少示波器之类的东西?

我的代码:

import { Auth, google } from "googleapis";

const main = async () => {
    const auth = new Auth.GoogleAuth({
        keyFile: "/path-to-service-account-file.json",
        scopes: "https://www.googleapis.com/auth/admin.directory.group.readonly",
    });
    const client = await auth.getClient();

    // Obtain a new drive client, making sure you pass along the auth client
    const admin = google.admin({ version: 'directory_v1', auth: client });

    const groups = await admin.groups.list();
    console.log(groups.data.groups);
}

main().then(() => process.exit(0)).catch(err => {
    console.error(err);
    process.exit(1);
});

该文件是(我认为)标准服务帐户文件:

{
  "type": "service_account",
  "project_id": "groupmembers-*******",
  "private_key_id": "*********",
  "private_key": ...,
  "client_email": "test-admin-nodejs@groupmembers-****.iam.gserviceaccount.com",
  "client_id": "*****",
  "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/test-admin-nodejs%40groupmembers-******.iam.gserviceaccount.com"
}

当我 运行 这段代码时,我得到以下响应:

    status: 400,
    statusText: 'Bad Request',
    request: {
      responseURL: 'https://admin.googleapis.com/admin/directory/v1/groups'
    }

我感兴趣的是它为我生成的不记名令牌。该错误还打印出请求信息:

config: {
    url: 'https://admin.googleapis.com/admin/directory/v1/groups',
    method: 'GET',
    userAgentDirectives: [ [Object] ],
    paramsSerializer: [Function (anonymous)],
    headers: {
      'x-goog-api-client': 'gdcl/5.1.0 gl-node/17.4.0 auth/7.14.1',
      'Accept-Encoding': 'gzip',
      'User-Agent': 'google-api-nodejs-client/5.1.0 (gzip)',
      Authorization: 'Bearer ya29.c.b0AX***********************************************jzxc........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................',
      Accept: 'application/json'
    },

我不知道这是否正常或相关,但我从未见过末尾带有一堆点的不记名令牌。

400 错误不是 authorization/authentication 问题,而是客户端请求问题。根据 official documentation,api 调用需要一些查询参数。其中之一是 customer 查询参数:

The unique ID for the customer's Google Workspace account. In case of a multi-domain account, to fetch all groups for a customer, fill this field instead of domain. As an account administrator, you can also use the my_customer alias to represent your account's customerId. The customerId is also returned as part of the Users

根据经验,这意味着您必须使用此值。尽管文档应该更好,并且应该明确说明这是必需的。因此,总而言之,您的请求应如下所示:

const groups = await admin.groups.list({
    customer: "my_customer"
});
console.log(groups.data.groups);