GCP 签名网址将内容配置设置为内联

Lau*_*182 1 java google-cloud-storage kotlin google-cloud-platform

在问这个问题之前,我做了很多研究,也做了很多测试,像往常一样,我不喜欢仅仅因为这个问题就问。

我无法使用 java 创建在浏览器中显示文件 (content-disposition:inline) 的签名 URL。

当我使用 PHP sdk 执行此操作时,没有遇到任何问题,我将签名的 url 复制并粘贴到浏览器中,文件就会显示在浏览器中。但是当对同一个文件使用java时,该文件会被下载。

在这篇文章中,它提到了一些关于清除元数据和附加“&response-content-disposition=inline”到签名网址的内容,谷歌云文档中也提到了这一点。

我尝试了多种方法,但我无法使其工作,当我按照文档中的指定附加“&response-content-disposition=inline”时,出现以下错误:

 <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>
Run Code Online (Sandbox Code Playgroud)

但它说这些参数不包含在签名的计算中,所以我不知道发生了什么。

在我尝试过的代码中:

    (transformed to kotlin)

    val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()
    val newMetadata: MutableMap<String, String> = HashMap()
    newMetadata["contentDisposition"] = "inline"
    blobInfo.toBuilder().setMetadata(newMetadata).build()

    val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS,Storage.SignUrlOption.withV4Signature())
        
    return signUrl.toString()
Run Code Online (Sandbox Code Playgroud)

但没有运气。

我认为应该有一种非常直接的方法来将内容处置设置为我想要的任何内容,但情况似乎并非如此。

我生成签名 url 的方法很简单:

val storage = this.getStorageDefaultInstance()

val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()

val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS, Storage.SignUrlOption.withV4Signature())

return signUrl.toString()
Run Code Online (Sandbox Code Playgroud)

有什么建议么?

编辑

我注意到,当我使用 PHP SDK 请求文件时,我得到响应标头"content-type: application/pdf",而在 Java 上我得到"content-type: application/octet-stream",也许这就是我需要的改变。

我尝试使用以下方法覆盖元数据:

    val newMetadata: MutableMap<String, String> = HashMap()
    newMetadata["contentDisposition"] = "inline"
    newMetadata["contentType"] = "application%2Fpdf"
    val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).setMetadata(newMetadata).build()
Run Code Online (Sandbox Code Playgroud)

尽管如此,还是没有运气。

Lau*_*182 5

所以,

我不断阅读和摆弄文档中的代码,直到我弄清楚为止。

我读得越多,所有的阅读和研究就开始变得更有意义。

因此,如果将来有人遇到同样的问题,我最终用来更改响应标头的代码是:

val storage = this.getStorageDefaultInstance()

val blobInfo = BlobInfo.newBuilder(BlobId.of(configuracion.bucket, fileName)).build()

//The query params
val queryParams: MutableMap<String, String> = HashMap()
queryParams["response-content-disposition"] = "inline"
queryParams["response-content-type"] = "application/pdf"

val signUrl = storage.signUrl(blobInfo, expiration, TimeUnit.MILLISECONDS, 
Storage.SignUrlOption.withQueryParams(queryParams), //This is the magic line
Storage.SignUrlOption.withV4Signature())

return signUrl.toString()
Run Code Online (Sandbox Code Playgroud)

为了更清楚地说明,当我阅读其他帖子和文档时,关于将参数(response-content-dispositionresponse-content-type)附加到url,我尝试了多种方法,在评论中的某处我读到了response-content-仅配置是不够的,对我来说就是这种情况,我还需要添加响应内容类型,但我的主要错误是在 url 签名后附加这些内容。

您需要创建 url 并将参数附加到查询字符串,然后再对 url 进行签名(上面的示例代码),并且 google api 将返回签名的 url,包括附加在查询字符串中的两个参数以及指定的值,因此您之后不需要修改url,就可以使用了。

希望这可以帮助其他人节省时间。