0

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

远程服务器返回错误:(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 页面底部截取的片段:

请求.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

谢谢

4

3 回答 3

1

您引用的curl请求使用gcloud auth application-default print-access-token命令在标头中传递访问令牌。每次运行时都会生成一个新令牌。令牌有一个过期时间,通常为 3600 秒。您可以通过运行自行检查:curl https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=GCLOUD_ACCESS_TOKEN。这将返回一个包含"expires_in"字段的有效负载。因此,将令牌作为GCLOUD_ACCESS_TOKEN环境变量传递会在过期后导致 403 错误。您应该做的是创建一个具有正确权限的服务帐户,下载一个带有其凭据的 json 并设置GOOGLE_APPLICATION_CREDENTIALS为 json 的路径。在下载凭据下查看此处以获取 .NET 中的示例。

于 2018-08-13T11:11:41.843 回答
1

我终于能够让它工作了。

有 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)在那里。

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

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

于 2018-08-16T09:17:31.940 回答
1

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

要从项目外部访问端点,请使用 API 网关,例如 APIGEE 或 AppEngine——它们可以为您提供更好的控制

于 2018-08-23T07:01:24.947 回答