首页 > 解决方案 > Shopify 生成的对谷歌云存储签名 URL 的 PUT 请求引发错误 MalformedSecurityHeader

问题描述

我正在尝试通过 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-uploadgoogle-cloud-storageshopifypre-signed-urlshopify-api

解决方案


一些建议供您尝试:

  • 在生成初始请求时(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 签名网址的经验


推荐阅读