13

我正在尝试使用“签名 URL”来访问/上传文件到 Google Cloud Storage (GCS)。

按照https://developers.google.com/storage/docs/accesscontrol#Signing-Strings上的说明进行操作

我做了什么:

  • 在 Google Cloud Console 上注册了“Web 应用程序”。
  • 使用已注册 Web 应用程序屏幕的“证书”部分的“生成新密钥”生成新的私钥。
  • 创建了要签名的字符串,并使用页面的“如何签名”部分提供的示例代码对其进行签名(只是对 Java 主程序的硬编码值进行了细微调整)。更新:为GcsSigner.java创建了一个要点。
  • 确保签名字符串是 URL 编码的。
  • 指定的 HTTP 标头:x-goog-api-version、x-goog-project-id、Content-Type。
  • 指定的 URL 参数:GoogleAccessId、签名、过期。
  • 使用 Postman(Chrome 扩展)模拟 PUT 请求。

但是,我仍然得到这个(状态:403 Forbidden):

<?xml version='1.0' encoding='UTF-8'?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message>
    <StringToSign>PUT

text/plain
1384084959392
x-goog-api-version:2
x-goog-project-id:99999
/mybucket/myfile.txt</StringToSign>
</Error>

即使我根据“StringToSign”中的值对字符串进行签名重试,我仍然会收到相同的错误。

在此处阅读各种相关帖子,但找不到任何解决方案,其中大部分是指x-goog-api-version:1我使用版本 2 时。

我错过了什么?任何帮助将不胜感激。

4

5 回答 5

10

最后设法使用签名的 URL 将文件放入 Google Cloud Storage。这是通过创建一个简单的 Java 程序来模拟的:

  • Server将字符串签名和编码为签名。
  • Uploader作为未经身份验证的用户,仅使用 提供的签名提交 PUT 请求Server。使用 Apache 的 HTTP 客户端库模拟浏览器。

您可以在此处查看演示应用程序

我真的不明白为什么当我通过 Chrome 的 Postman 扩展提交时它不起作用。

于 2013-11-15T01:58:56.403 回答
4

虽然文档说Content-Type是可选的,但这实际上意味着您must设置正确content-Type对应于您的 http 请求标头。

在这种情况下,您必须添加content-type: text/plain签名字符串。

https://cloud.google.com/storage/docs/access-control/create-signed-urls-program

于 2016-04-29T12:54:10.020 回答
2

我在 PUT 和签名 URL(使用 GAE Cloud Endpoints)方面苦苦挣扎,但这是我需要做的两件事:

  1. 确保您拥有最新的 GAE gradle 依赖项。自动生成的但 android studio 并不总是最新的。
  2. 对于 PUT,您需要让要签名的字符串如下所示:

    String url_signature = sign(verb + "\n" + contentMD5 + "\n" + contentType + "\n" + expire + "\n" + "/" + BUCKET_NAME + "/" + objectName );

如此处所述:https ://cloud.google.com/storage/docs/access-control/signed-urls格式为:

StringToSign = HTTP_Verb + "\n" +
               Content_MD5 + "\n" +
               Content_Type + "\n" +
               Expiration + "\n" +
               Canonicalized_Extension_Headers +
               Canonicalized_Resource

那些返回 "\n" 很重要。如果你有太多或不够,你会得到那个错误。例如,如果您没有传递 contentMD5,则只需传递一个空字符串,这样您就可以获得正确的 return "\n" 数量

于 2016-05-07T22:41:54.297 回答
1

在查看您的代码时,您能否尝试通过省略以下标题来创建stringToSign -

"x-goog-api-version:2\n" +
"x-goog-project-id:1234\n" +

如下所示 -

 String stringToSign = "PUT\n" +
                "\n" +
                "text/plain\n" +
                "1384084959392\n" +
                "/test-bucket/bob.txt";

现在尝试生成签名 URL。

谢谢

于 2013-11-13T06:20:37.413 回答
1

要从浏览器运行签名的 url,您必须设置 HTTP 标头。在https://developers.google.com/storage/docs/accesscontrol#Construct-the-String

Content_Type 可选。如果您提供此值,客户端(浏览器)必须提供此 HTTP 标头设置为相同的值。有一个词必须

因此,如果您为符号字符串提供 Content_Type,则必须在浏览器 http 标头中提供相同的 Content_Type。当我在浏览器标头中设置 Content_Type 时,我也遇到了同样的问题,我能够下载文档。

于 2014-08-04T11:54:30.790 回答