【问题标题】:PUT request to google cloud storage signed URL generated by Shopify throws error MalformedSecurityHeaderShopify 生成的对谷歌云存储签名 URL 的 PUT 请求引发错误 MalformedSecurityHeader
【发布时间】:2020-07-20 12:04:25
【问题描述】:

我正在尝试通过 Shopify GraphQL Admin API 将 .glb 文件上传到 Shopify 商店中的产品。为此,它首先返回一个谷歌云存储签名的 URL,我应该通过 HTTP PUT 请求将我的文件上传到那里。上传后,我应该使用另一个 API 调用将相同的 URL 附加到产品。

这个问题是关于上传到云存储签名 URL 的文件。我包括所有这些细节,以使这个问题很容易得到回答。 所以,请阅读到最后

  1. Shopify 为我提供的数据如下所述。
{
  "data": {
    "stagedUploadsCreate": {
      "stagedTargets": [
        {
          "parameters": [
            {
              "name": "GoogleAccessId",
              "value": "threed-model-service--6bgx7cbe@shopify-applications.iam.gserviceaccount.com"
            },
            {
              "name": "key",
              "value": "models/a6436c066064bac3/windmill.glb"
            },
            {
              "name": "policy",
              "value": "eyJleHBpcmF0aW9uIjoiMjAyMC0wNy0yMVQwOToxNjoxMFoiLCJjb25kaXRpb25zIjpbWyJlcSIsIiRidWNrZXQiLCJ0aHJlZWQtbW9kZWxzLXByb2R1Y3Rpb24iXSxbImVxIiwiJGtleSIsIm1vZGVscy9hNjQzNmMwNjYwNjRiYWMzL3dpbmRtaWxsLmdsYiJdLFsiY29udGVudC1sZW5ndGgtcmFuZ2UiLDE5NzE3MiwxOTcxNzJdXX0="
            },
            {
              "name": "signature",
              "value": "vz+OdcEmD9Kbv2FbXdxWNUk59XO2GmXzhvtDswXbDQNcyZpUufI85z5x2PFGv/XZ+tSBsl/S393pmy0Bu9xG7oVgOZcMIWEbOIm9kXgQunbjKQY3Ff3BBpMocB0xazzlYmckZozdJ8ZZkyox/c/gEe1QaxqW4+419iufuFHy4Bp3LL/aUr+ATNChwn9Dn8+XnHMOckZxDlbiggcF3dx+yBuTFia8FneaVSiU0M5DIWmHqHb2YDCV0KtEP6jfTj/PQVUjS8pn8EGhrRaMx7Q2A5G8Pycgc9H35hqJnnUKCTa3AYeyI45RbhddYnIWw9YrAADXuQYlVCo6LYBHjxsCWA=="
            }
          ],
          "resourceUrl": "https://storage.googleapis.com/threed-models-production/models/a6436c066064bac3/windmill.glb?external_model3d_id=bW9kZWwzZC00MDg5Ng==",
          "url": "https://storage.googleapis.com/threed-models-production/models/a6436c066064bac3/windmill.glb?external_model3d_id=bW9kZWwzZC00MDg5Ng=="
        }
      ],
      "userErrors": []
    }
  }
}
  1. 使用这些参数,我构造了一个签名 URL,如下所示。
resourceUrl+"&signature="+signature+"&key="+key+"&policy="+policy+"&GoogleAccessId="+GoogleAccessId

例如:

https://storage.googleapis.com/threed-models-production/models/a6436c066064bac3/windmill.glb?external_model3d_id=bW9kZWwzZC00MDg5Ng==&signature=vz+OdcEmD9Kbv2FbXdxWNUk59XO2GmXzhvtDswXbDQNcyZpUufI85z5x2PFGv/XZ+tSBsl/S393pmy0Bu9xG7oVgOZcMIWEbOIm9kXgQunbjKQY3Ff3BBpMocB0xazzlYmckZozdJ8ZZkyox/c/gEe1QaxqW4+419iufuFHy4Bp3LL/aUr+ATNChwn9Dn8+XnHMOckZxDlbiggcF3dx+yBuTFia8FneaVSiU0M5DIWmHqHb2YDCV0KtEP6jfTj/PQVUjS8pn8EGhrRaMx7Q2A5G8Pycgc9H35hqJnnUKCTa3AYeyI45RbhddYnIWw9YrAADXuQYlVCo6LYBHjxsCWA==&key=models/a6436c066064bac3/windmill.glb&policy=eyJleHBpcmF0aW9uIjoiMjAyMC0wNy0yMVQwOToxNjoxMFoiLCJjb25kaXRpb25zIjpbWyJlcSIsIiRidWNrZXQiLCJ0aHJlZWQtbW9kZWxzLXByb2R1Y3Rpb24iXSxbImVxIiwiJGtleSIsIm1vZGVscy9hNjQzNmMwNjYwNjRiYWMzL3dpbmRtaWxsLmdsYiJdLFsiY29udGVudC1sZW5ndGgtcmFuZ2UiLDE5NzE3MiwxOTcxNzJdXX0=&GoogleAccessId=threed-model-service--6bgx7cbe@shopify-applications.iam.gserviceaccount.com

  1. 然后我尝试使用 POSTman 中的 .glb 文件向该 URL 发出 PUT 请求,如下图所示 -->

带有以下标题。

  1. 但我没有收到成功响应。事实上,我收到以下消息的 400 错误。
<?xml version='1.0' encoding='UTF-8'?>
<Error>
    <Code>MalformedSecurityHeader</Code>
    <Message>Your request has a malformed header.</Message>
    <ParameterName>signature</ParameterName>
    <Details>Signature was not base64 encoded</Details>
</Error>

有人可以指出我在这里做错了什么吗?几天来我一直在处理这个错误并阅读了很多问题和文章,但无法让它发挥作用。因此,非常感谢任何有用的建议。

【问题讨论】:

    标签: file-upload google-cloud-storage shopify pre-signed-url shopify-api


    【解决方案1】:

    一些建议供您尝试:

    • 在生成初始请求时(Shopify 在这种情况下执行此操作),GCS 通常包含该请求的 HTTP 标头并将它们包含在请求签名中,并期望上传请求(您尝试执行的请求)匹配相同HTTP 标头值。 这意味着建议您仅在您的签名密钥上传请求中包含 Shopify 在其请求中指定的那些标头,不要包含任何额外内容。因此,首先尝试删除 Shopify 未记录的所有 HTTP 标头(例如 POSTMAN 添加的标头)并确保所有标头值都遵循 Shopify 文档(例如 Content-Type 应该匹配)
    • 您需要确保签名参数采用预期的名称和格式:
      1. 签名值字段被命名为:x-goog-signature 而不是 signature(这可能是您收到 GCS 找不到预期参数的错误的可能原因)
      2. 您可能还必须提供签名算法密钥 (x-goog-algorithm)
      3. 您可能还需要其他密钥,具体取决于身份验证等其他因素 我想说这些应该由 Shopify SDK 和/或示例记录

    为您简化/加快操作的一个建议可能是使用 Google Cloud Utils(gsutil 命令行工具)创建签名的 url 请求,然后尝试在您的代码中重现相同的行为 有关更多信息,请参阅以下链接:

    https://cloud.google.com/storage/docs/access-control/signed-urls https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers#gsutil

    然后在熟悉签名 url 格式之后,您可以查看以下示例代码,了解如何在您自己的代码中进行操作:

    https://cloud.google.com/storage/docs/access-control/signing-urls-manually

    供您在阅读文档时参考,您尝试创建的签名 URL 类型是不可恢复上传(使用单个 PUT 请求)而不是可恢复(使用初始 POST 加上一系列 PUT) 抱歉,我没有与 Shopify 合作过,但以上内容来自我使用 GCS 签名网址的经验

    【讨论】:

    • 是的,正如你提到的,我也尝试使用x-goog-signature 而不是signature 等等。但是,如果我这样使用,它需要 x-goog-credential 参数的值,但 Shopify 提供的参数值都与该参数值不匹配,即导致错误。
    • 正如您在答案中提到的,这些东西应该在 Shopify API 文档中明确提及,但没有找到。我还通过电子邮件发送了 Shopify 支持,他们承诺很快将该信息添加到文档中,但我不知道什么时候会发生,我想尽快解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 2018-07-22
    • 2013-12-27
    • 2019-04-09
    • 2018-08-30
    • 2014-10-23
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多