google-app-engine - Compute Engine API 调用失败并显示 http 404

标签 google-app-engine google-api google-compute-engine

我需要一些关于从 App Engine 代码中调用 Google Compute Engine API 的帮助。以下是我用来获取计算引擎实例列表的部分代码(简化版)

try {
            final AppIdentityService appIdService = AppIdentityServiceFactory
                    .getAppIdentityService();
            AppIdentityService.GetAccessTokenResult result = appIdService
                    .getAccessTokenUncached(Collections
                            .singletonList(ComputeScopes.COMPUTE));
            String accessToken = result.getAccessToken();
            String url = "https://www.googleapis.com/compute/v1/projects/MYPROJECTID/zones/us-central1-b/instances";
            String payload = "";

            // Create HTTPRequest and set headers
            HTTPRequest httpRequest = new HTTPRequest(new URL(url.toString()),
                    HTTPMethod.GET, FetchOptions.Builder.doNotFollowRedirects());

            httpRequest.addHeader(new HTTPHeader("Authorization", "OAuth "
                    + accessToken));

            httpRequest.addHeader(new HTTPHeader("Host", "www.googleapis.com"));
            httpRequest.addHeader(new HTTPHeader("Content-Length", Integer
                    .toString(payload.length())));
            httpRequest.addHeader(new HTTPHeader("Content-Type",
                    "application/json"));
            httpRequest.addHeader(new HTTPHeader("User-Agent",
                    "google-api-java-client/1.0"));
            httpRequest.setPayload(payload.getBytes());

            URLFetchService fetcher = URLFetchServiceFactory
                    .getURLFetchService();
            HTTPResponse httpResponse = fetcher.fetch(httpRequest);

            int responseCode = httpResponse.getResponseCode();
            if ((responseCode == 200) || (responseCode == 204)) {
                String contentStr = new String(httpResponse.getContent());
                return extractIpsAndInstanceNames(contentStr, prefix);
            } else {
                logger.warning("Failed. Response code " + responseCode
                        + " Reason: " + new String(httpResponse.getContent()));
            }

如您所见,我正在使用 AppIdentity 获取访问 token 。然后在 API 调用的请求 header 中使用它。

基本上每次调用失败并出现以下错误

Failed. Response code 404 Reason: {
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "notFound",
    "message": "The resource 'projects/MYPROJECTID' was not found"
   }
  ],
  "code": 404,
  "message": "The resource 'projects/MYPROJECTID' was not found"
 }
}

有趣的是,如果我使用以下 webapp https://developers.google.com/compute/docs/reference/latest/instances/list#try-it进行相同的 API 调用它会成功。

所以我查看了当这个网络应用发出请求时发送了哪些数据,并复制了不记名 token 字符串并将其用于“授权” header 中。奇怪的是,请求现在已成功完成,无需更改任何其他内容。基本上,该应用程序使用用户同意 Oauth2 类型的 token - 所以对我来说,通过 AppIdentity 获得的 token 似乎存在一些问题。 有人能指出我正确的方向吗?谢谢!

最佳答案

我遇到了同样的问题,并且能够解决它,或者我应该说解决方法,但对我来说并不完全有意义。希望对这个问题有真正了解的人可以进一步解释。此解决方案与 E. Anderson 的回答类似,但有所不同,因为 App Engine 和 Compute Engine 都在同一个项目中。

这是我做的:

  1. 在真正运行的 App Engine 中(不是在本地开发人员模式下)打印出服务帐户电子邮件。在 Go 运行时,我使用了 appengine.ServiceAccount(ctx)
  2. Google Developers Console ,转到项目的“权限”页面,并将您在上一步中获得的电子邮件地址添加为项目成员。

完成此操作后,我就能够从 App Engine 向 Compute Engine REST API 发出请求。我不知道为什么需要这一步。

关于google-app-engine - Compute Engine API 调用失败并显示 http 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21062286/

相关文章:

Python webapp 动态路径

java - 谷歌应用程序引擎。如何自定义登录页面?

java - 在 Jetty 实例之间共享 Memcached

google-api - 批量插入时资源Id无效

python - 使用 bash 或 python 脚本启动和停止 GCE 实例

mysql - 来自 GCE 实例的 CloudSQL ERROR 2013

java - 超过 3 列的 Google App-Engine Java 过滤

python - 使用 python 在 Gmail 中发送邮件

google-compute-engine - gcloud docker push 403 禁止

google-api - 我们是否需要隐藏 google oauth 客户端 ID?