file-upload - Shopify 生成的对谷歌云存储签名 URL 的 PUT 请求引发错误 MalformedSecurityHeader
问题描述
我正在尝试通过 Shopify GraphQL Admin API 将 .glb 文件上传到 Shopify 商店中的产品。为此,它首先返回一个谷歌云存储签名的 URL,我应该通过 HTTP PUT 请求将我的文件上传到那里。上传后,我应该使用另一个 API 调用将相同的 URL 附加到产品。
这个问题是关于将该文件上传到云存储签名 URL 的。我包括所有这些细节,以使这个问题很容易得到回答。所以,请读到最后。
- 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": []
}
}
}
- 使用这些参数,我构造了一个签名 URL,如下所示。
resourceUrl+"&signature="+signature+"&key="+key+"&policy="+policy+"&GoogleAccessId="+GoogleAccessId
例如:
带有以下标题。
- 但我没有得到成功的回应。事实上,我收到以下消息的 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>
有人可以指出我在这里做错了什么吗?几天来我一直在处理这个错误并阅读了很多问题和文章,但无法让它发挥作用。因此,非常感谢任何有用的建议。
解决方案
一些建议供您尝试:
- 在生成初始请求时(Shopify 在这种情况下执行此操作),GCS 通常包含该请求的 HTTP 标头并将它们包含在请求签名中,并期望上传请求(您尝试执行的请求)匹配相同的 HTTP 标头值. 这意味着建议您在签名密钥上传请求中仅包含 Shopify 在其请求中指定的那些标头,不要包含任何额外内容。因此,首先尝试删除 Shopify 未记录的所有 HTTP 标头(例如 POSTMAN 添加的标头)并确保所有标头值都遵循 Shopify 文档(例如 Content-Type 应该匹配)
- 您需要确保签名参数采用预期的名称和格式:
- 签名值字段名为:
x-goog-signature
而不是signature
(这可能是您收到 GCS 找不到预期参数的错误的可能原因) - 您可能还必须提供签名算法密钥 (
x-goog-algorithm
) - 您可能还需要其他密钥,具体取决于身份验证等其他因素,所以我想说这些应该由 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 签名网址的经验
推荐阅读
- java - 实现 JMS MDB 的类的构造函数实际上是如何工作的?
- xamarin.forms - 推送通知:通知文本与其他数据
- r - 在R中分解多个谷歌表单条目
- php - 所有数据库记录都得到更新,而不是只有 1 个 CodeIgniter 4
- ssl-certificate - S3 站点的 AWS 证书待验证
- android - 将屏幕方向锁定为纵向 - React Native Android
- c++ - doxygen 文档中 c++ 枚举的十六进制值
- amazon-cognito - 如何在 aws cognito 中禁用 MFA?
- python - Django中多个用户相互依赖的问题
- html - ZIndex 在 flexbox 列表中堆叠 IFRAME 和 DIV