克服 /compute/v1/projects/{project}/zones 上的 401?

Overcoming 401 on /compute/v1/projects/{project}/zones?

Reverse-engineering gcloud 工具—使用 mostly—I was able to get auth tokens generated, and even selected the same scope (double checking at https://www.googleapis.com/oauth2/v1/tokeninfo):

http://[redacted]/callback?state=[redacted]&code=[redacted]&scope=email+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&authuser=0&prompt=consent

https://oauth2.googleapis.com:443/token?grant_type=authorization_code&code=[redacted]&redirect_uri=[redacted]/callback&client_id=[redacted]apps.googleusercontent.com&client_secret=[redacted]

Headers 我尝试使用

来达到 /zones/list endpoint
Content-Type: application/json
charset: utf-8
Authorization: Bearer [redacted]
X-Goog-User-Project: [redacted]

我也试过将 access_token=[redacted] 放入我的查询字符串中。但无论我做什么,我总是得到:

{
  "error": {
    "code": 401,
    "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
    "errors": [
      {
        "message": "Login Required.",
        "domain": "global",
        "reason": "required",
        "location": "Authorization",
        "locationType": "header"
      }
    ],
    "status": "UNAUTHENTICATED"
  }
}

其他端点,如 /projects/list 似乎可以使用此访问令牌(在 header 中)。我做错了什么?

正如我从错误消息中看到的那样,您收到了 401 http 状态代码。这意味着您使用的访问令牌不允许您访问(未授权)列出区域。 而这里你要知道你不能比较zone.list and projects.list。事实上:

  • zone.list 是计算引擎 API 的一部分,而 projects.list 是资源管理器 API
  • 的一部分
  • zone.list 需要 compute.zones.list 权限,它是 Compute Engine 角色的一部分,例如 Compute Viewer 而 projects.list 需要 resourcemanager.projects.list ,您会发现很多角色甚至 Browser 角色,就权限数量而言,这是最小的角色(我认为)。
  • 总而言之,通常您使用的身份访问令牌可以访问 projects.list 但不能访问 zone.list。 例如,此身份仅具有Browser角色。

然后,关于您如何获取访问令牌的这句话引起了我的注意:

Reverse-engineering the gcloud tool

您需要知道获取访问令牌非常容易。

  1. 运行 gcloud auth login 通过基于 Web 的授权流程获取您的用户帐户的访问凭据。
  2. 运行 gcloud auth print-access-token 为您的用户帐户打印访问令牌,因此他的权限。

因此,如果您的用户帐户具有具有 compute.zones.listresourcemanager.projects.list 权限的角色(例如 Compute Viewer 角色具有这两种权限),您将能够成功调用两个端点。

最后,这是一个 curl 示例,使用生成的访问令牌列出区域:

curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json" https://compute.googleapis.com/compute/v1/projects/<PROJECT_ID>/zones

原来我的原始解决方案是 100% 正确的。出于某种奇怪的原因,保存在我的结构的访问令牌字段中的字符串与从远程身份验证流程中收集的字符串不同。