尝试通过 REST API 将图像发送到我的自定义 AutoML 模型时出现“(403) Forbidden”

"(403) Forbidden" when trying to send an image to my custom AutoML model via the REST API

我在 .NET Web 应用程序中实现自定义 AutoML 模型时遇到问题,该模型允许通过 REST API 发送图像以供识别。我不断收到错误消息。

The remote server returned an error: (403) Forbidden.

我有一个图像并将其转换为称为 imageBytesString 的字节串,并创建了 jsonRequest 对象,如下所示:

string jsonRequest = "{\"payload\":{\"image\":{\"imageBytes\":\"" + imageBytesString + "\"},}}";`

然后我正在执行如下 POST 请求:

WebRequest request = WebRequest.Create(@"https://automl.googleapis.com/v1beta1/projects/PROJECT_ID/locations/us-central1/models/MODEL_ID:predict");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("Authorization", "Bearer GCLOUD_ACCESS_TOKEN");

using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
    streamWriter.Write(jsonRequest);
}

然后当它点击 request.GetResponse(); 时,如果给我上面的错误,没有其他信息。

作为参考,这些是从我的自定义 AutoML 模型的 PREDICT 页面底部截取的片段:

request.json:

{
  "payload": {
    "image": {
      "imageBytes": "YOUR_IMAGE_BYTE"
    },
  }
}

执行请求:

curl -X POST -H "Content-Type: application/json" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  https://automl.googleapis.com/v1beta1/projects/PROJECT_ID/locations/us-central1/models/MODEL_ID:predict -d @request.json

谢谢

您引用的 curl 请求使用 gcloud auth application-default print-access-token 命令在 header 中传递访问令牌。这会在每次 运行 时产生一个新的标记。令牌有一个过期时间,通常为 3600 秒。您可以通过 运行: curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=GCLOUD_ACCESS_TOKEN 自行检查。这将 return 包含 "expires_in" 字段的有效负载。因此,将令牌作为 GCLOUD_ACCESS_TOKEN 环境变量传递将在其过期后导致 403 错误。您应该做的是在 下载凭据 下创建一个 service account with the correct permissions, download a json with its credentials and set GOOGLE_APPLICATION_CREDENTIALS to the json's path. Check here 作为 .NET 中的示例。

我终于能够让它工作了。

有 2 个问题需要解决才能正常工作。

首先;出于某种原因,当我最初创建服务帐户并输入命令 gcloud auth activate-service-account --key-file="[/PATH/TO/KEY/FILE.json] 时,它告诉我它有效并且服务帐户已添加到 gcloud auth list 列表中。但是再次检查时,它不在那里,所以我再次 运行 它。

其次;我使用以下命令获取访问令牌:

gcloud auth application-default print-access-token

相反,我尝试使用通过以下命令收到的访问令牌:

gcloud auth print-access-token

(没有application-default)。

完成这两件事后,我现在可以成功发送图像请求并接收预测响应。

但似乎我仍然必须每小时获取一个新的访问令牌...但我认为这是另一个问题。

更好的解决方案是仅从同一项目内访问 Auto ML 端点(这样您就不需要访问令牌)。

要从项目外部访问端点,请使用 API 网关,例如 APIGEE 或 AppEngine——它们会给你更好的控制