【问题标题】:Google cloud storage upload using generic signed url and curl使用通用签名 url 和 curl 上传 Google 云存储
【发布时间】:2015-05-06 02:15:50
【问题描述】:

我正在尝试从命令行将文件放入 Google Cloud Storage (GCS) 存储桶。在稍后阶段,这将在用户端部署的脚本中使用,无需任何类型的用户可见身份验证。

到目前为止,我生成了一个这样的签名网址:

gsutil signurl -p notasecret -m PUT -d 1d myserviceaccount.p12 gs://mybucket/testfile

这会产生类似的东西

https://storage.googleapis.com/mybucket/testfile?GoogleAccessId=myserviceaccount@developer.gserviceaccount.com&Expires=1430963040&Signature=gMf2h95bNmolizUGYrsQ%2F%2F%2FiHxW14I%2F0EOU3ZSFWtfCwNqSyok3iweQiuPxYXH4b26FeDSrmFOXB58%2B%2B%2BiAOJ%2B1gdLC9Y%2BkeUdbrjH0eGTW0NVsM1AWY2LsQ3dYf5Ho%2Bos1Fk26EsLJlD096Ku9aWqLW%2FpL%2FBSsUIfHijrFJPdI%3D

下一步(在用户端)将是curl 使用 PUT 请求上传文件。像这样:

curl -X PUT --data-binary @testfile 'https://storage.googleapis.com/mybucket/testfile?GoogleAccessId=myserviceaccount@developer.gserviceaccount.com&Expires=1430963040&Signature=gMf2h95bNmolizUGYrsQ%2F%2F%2FiHxW14I%2F0EOU3ZSFWtfCwNqSyok3iweQiuPxYXH4b26FeDSrmFOXB58%2B%2B%2BiAOJ%2B1gdLC9Y%2BkeUdbrjH0eGTW0NVsM1AWY2LsQ3dYf5Ho%2Bos1Fk26EsLJlD096Ku9aWqLW%2FpL%2FBSsUIfHijrFJPdI%3D'

我可以让它与存储桶中的现有文件和 GET 请求(用于下载)一起使用,但它似乎不适用于上传。 curl 向我抛出服务器的响应,并带有这样的错误消息:

<?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

application/x-www-form-urlencoded
1430963040
/mybucket/testfile</StringToSign>
</Error>

这对我来说很有意义,因为显然我不仅仅是发出一个简单的 PUT 请求,而是一个针对特定大小的特定文件的请求,而由“gsutil signurl”计算的签名在计算时间。

不知何故,我的印象是(例如,基于gsutil signurl documentation 和帖子How to allow anonymous uploads to cloud storage 中描述的最后一个用例)应该可以生成一个通用的签名 url 用于上传,然后使用它之后。我只是误解了这一点还是有办法解决curl 请求?

对此的任何想法表示赞赏。但是,我希望它可以使用“最少的工具”,即理想情况下只有 shell 和 curl,而不是其他编程语言。

编辑: 通过制定确切的问题来组织思想是解决问题的第一步。我现在意识到

curl -X PUT -T - [request-url] < testfile

确实解决了眼前的问题。但是,这意味着如果多个用户使用相同的签名 url,他们将写入同一个文件。文档建议您可以在创建签名 url 时省略对象名称,即使用

gsutil signurl -p notasecret -m PUT -d 1d myserviceaccount.p12 gs://mybucket/

据推测,这将允许任何拥有生成的签名 url 的人将任何类型的任何对象放入我的存储桶中。只有我没有完成这项工作,因为我不知道你如何告诉 GCS 你实际上正在写入哪个对象。

【问题讨论】:

  • 您对此有进一步了解吗?我遇到了同样的问题,访问被拒绝。
  • 自这些编辑以来,这里没有什么可报告的。不幸的是。
  • 我遇到了同样的问题
  • > 文档建议您可以在创建签名 url 时省略对象名称 - 您在哪里看到的?您必须指定对象名称。
  • 也许这会有所帮助。我有一个 appengine Python 脚本,它使用表单帖子将文件发送到 GCS。发布请求已签名。 Appengine 使创建后 HTML 表单变得非常容易,无需本地 p12 键。更多信息:github.com/voscausa/appengine-gcs-upload

标签: google-app-engine curl


【解决方案1】:

这也让我发疯了。原来它是 curl 命令的 binary-file 部分。试试这个:

curl -X PUT --upload-file me.jpeg $SIGNED_URL

【讨论】:

    【解决方案2】:

    如果资源没有指定单个对象,您可以通过将 URL 参数添加到带有对象名称的请求中来单独指定。例如:

    curl -X PUT -T - [request-url]?name=[object-name] &lt; testfile

    这肯定适用于storage/v1,尽管我还没有尝试过使用签名 URL。

    【讨论】:

    • 这很有趣,谢谢。不幸的是,我无法让它工作。 storage/v1 方法使用不同的 URL 和 POST 方法来插入对象。另一方面,gsutil signurl 不支持 POST 方法(它使用 PUT)。只是用https://www.googleapis.com/storage/v1/b/mybucket/o?GoogleAccessId=...as_before...?name=myobject 替换我上面的 PUT 请求 URL 似乎对我也不起作用。
    【解决方案3】:

    我遇到了类似的问题(403禁止)。
    事实证明,出于安全考虑,我用它来编组每个响应的 json 库将用 \u0026 替换 &amp;。所以 url 在程序中可能是正确的,但在客户端是无效的
    所以我猜想你的网址的Signature 查询字符串中可能存在一些字符串编码错误,因为与我的\u0026 相比,签名字符串更难检测到错误。

    【讨论】:

    • 谢谢。我不认为这是一个 url 编码问题,因为命令 curl -X PUT -T - [request-url] &lt; testfile 对我有用。您收到的 HTTP 403 响应是一个强有力的指标,表明该 URL 的某些内容不正确,并且请求了错误的对象或不存在的对象。很高兴听到您能找出原因并加以解决。
    猜你喜欢
    • 2019-04-18
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    • 2020-06-28
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多