【问题标题】:send metatags through Google Cloud Signed URL with Django使用 Django 通过 Google Cloud 签名 URL 发送元标记
【发布时间】:2021-09-30 06:46:59
【问题描述】:

我正在使用签名的 url 在我的谷歌存储上获取或发布/发布视频 fileq。我的模块在signed_url V4 上引用,并且运行良好。 我想在我的请求中添加一些元数据标签,以便更有效地管理与 GCS 相关的费用。但是由于我添加了这些标头,因此请求未能返回 cors 策略错误:(我已缩短上面块中的签名以使其更具可读性)

Access to XMLHttpRequest at 'https://test-dev-slotll.storage.googleapis.com/uploads/dave/FR/eaa678c9/2020/9/785f/f45d3d82-785f_full.mp4?X-
Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=dev-storage%40brilliant-tower-264412.iam.gserviceaccount.com%2F20200926%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20200926T093102Z&X-Goog-Expires=3600&X-Goog-SignedHeaders=host%3Bx-goog-meta-account&x-goog-signature=6fbb27e[...]bd0891d21' from origin 'http://localhost:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

以及详细信息:

   <Error>
    <Code>MalformedSecurityHeader</Code>
    <Message>Your request has a malformed header.</Message>
    <ParameterName>x-goog-meta-account</ParameterName>
    <Details>Header was included in signedheaders, but not in the request.</Details>
   </Error>

cors 被配置为允许我存储桶上的几乎所有东西:

[{"maxAgeSeconds": 3600, "method": ["*"], "origin": ["*"], "responseHeader": ["*"]}]

这里是 Python/Django 函数

def _get_signed_url(self, http_method="GET"):
        """' create a signed url with google storage
        create a 'GET' request by default,
        add method='w' or 'put' to create a 'PUT' request
        get_signed_url('w')->PUT / get_signed_url()->GET
        """
        if http_method.lower() in ["w", "put", "post"]:
            http_method = "PUT"
        else:
            http_method = "GET"

        signed_url = generate_signed_url(
            settings.GS_BUCKET_NAME,
            self.file.name,
            subresource=None,
            expiration=3600,
            http_method=http_method,
            query_parameters=None,
            headers={'x-goog-meta-language':'french','x-goog-meta-account':'david',},
        )

        return signed_url

正如我在上面写的,get_signed_url() 方法是从signed_url V4 复制而来的 如果我替换headers = {'x-goog-meta-language':'french','x-goog-meta-account':'david',}, hearders = {}headers = None (就像以前一样,它工作正常

最后,当我点击签名网址给出的链接时,我收到一条错误消息:

签名的 url 以及 blob 上传或下载在没有标头的情况下可以正常工作几个月,但我不明白为什么服务器会响应标头元标记格式错误... 我将不胜感激 谢谢!

【问题讨论】:

  • 如果您修复了 MalformedSecurityHeader 错误的原因,您可能会发现您现有的 CORS 配置已经按预期工作。当响应状态不是 200 OK 而是一些错误时,这是​​正常的,并且预期响应不会有 Access-Control-Allow-Origin 响应头。
  • 是的,我不怀疑 cors。当我不发送额外的标头并且所有内容都通过 cors 授权时,签名的 url 有效。我不明白为什么我的元数据格式错误以及为什么 headers = {'x-goog-meta-language':'fr'} 不正确...
  • 我对 Google Cloud 的知识了解为零,但我确实注意到问题中引用的错误是,“标头包含在签名标头中,但未包含在请求中。” i> 这似乎表明问题不在于标头的值格式不正确,而是请求标头完全丢失了。因此,您可能想要更新问题以显示发出请求的前端 JavaScript 代码部分的 sn-p。该代码是否确保正确的标头包含在请求中?
  • 我找到了stackoverflow.com/questions/56779529/…,这似乎与您遇到的问题相同。那里删除的答案说,“这个错误意味着您在创建签名时包含了 HTTP 标头 。这意味着客户端在上传时也必须包含此标头。在签名之前删除标头或修改客户端软件以在发出 HTTP 请求时包含 标头。”
  • 我了解到问题出在 HTTP 请求上。但是该 URL 是由 GCP 通过“签名的 url v4 脚本”提供的“generate_signed_url()”方法构建的。我只是通过 django 模板将给定的 URL 发送给客户端,该模板“打印”带有签名 URL 的链接。当用户单击该 URL 给出的链接时,客户端会发送一个 GET 请求。由于链接本身无法修改请求,如何在请求中插入标头?

标签: python django google-cloud-platform google-cloud-storage


【解决方案1】:

当我对来自 GCP 的预签名 URL 执行 GET 请求时,我收到了相同的错误消息。添加 content-type: "application/octet-stream" 为我解决了这个问题。

ajaxCall_getFile = $.ajax({    
xhr: function() {
var xhr = new window.XMLHttpRequest();
return xhr;
},
type: 'GET',
url: <PRE-SIGNED URL>,
contentType: "application/octet-stream",
processData: false,
success: function(file_data){
  alert("file downloaded");
},
error: function(err) {
  alert('Download failed, please try again.');
}
});

【讨论】:

    【解决方案2】:

    正如@Sideshowbarker 在他的cmets 中所暗示的那样,问题来自客户。 签名的 url 用于通过 ajax 将文件发送到存储,但没有向 ajax 添加自定义标头。 通过在 ajax 中指定 headers,带有自定义元数据的签名 url 的 PUT 请求运行良好。

    function ajaxSendToStorage(uuid, url) {
      // Sending ONE file to storage
      var file = getFileById(uuid);
      $.ajax({
        method: "PUT",
        contentType: file.type,
        processData: false,
        dataType: "xml",
        crossDomain: true,
        data: file,
        url: url,
        headers: {"x-goog-meta-account":"david","x-goog-meta-language": "fr"},
        success: function() {},
        complete: function() {},
      });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 2022-06-14
      • 2018-06-05
      • 2016-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多