api - Google 存储桶签名 URL 403

标签 api go google-cloud-storage http-status-code-403 bucket

我正在做一个简单的 rest API,它执行以下操作:

  • 获取base64编码的图片
  • 解码
  • 将其存储在特定的谷歌存储桶上

现在,在 GET 动词上,我的 api 返回一个指向存储桶图像的签名 url。

我编写了一个有效的测试:

    initialization stuff
    ...
    BeforeEach(func() {
        mockStringGenerator.On("GenerateUuid").Return("image1")

        // First store
        image, _ = ioutil.ReadFile("test_data/DSCF6458.JPG")
        encodedImage = b64.RawStdEncoding.EncodeToString(image)
        fileName, storeError = storage.Store(ctx, encodedImage, "image/jpeg")

        // Then get
        uri, getError = storage.Get(ctx, fileName)
        getResponse, _ = http.Get(uri)

        // Finally delete
        deleteError = storage.Delete(ctx, fileName)
    })

    // Only 1 test to avoid making too much connexion
    It("should create, get and delete the image", func() {
        // Store
        Expect(storeError).To(BeNil())
        Expect(fileName).To(Equal("image1.jpg"))

        // Get
        Expect(getError).To(BeNil())
        Expect(getResponse.StatusCode).To(Equal(http.StatusOK))
        b, _ := ioutil.ReadAll(getResponse.Body)
        Expect(b).To(Equal(image))

        // Delete
        Expect(deleteError).To(BeNil())
    })

但是当我运行 .exe 并尝试向 postman 发出 ssome 请求时,我在签名的 url 中收到 403 错误:

<?xml version='1.0' encoding='UTF-8'?>
<Error>
    <Code>AccessDenied</Code>
    <Message>Access denied.</Message>
    <Details>Anonymous caller does not have storage.objects.get access to teddycare-images/08d8c508-d97d-48d3-947b-a7f216f622db.jpg.</Details>
</Error>

有什么想法吗?我真的不明白... 伙计们救救我

[编辑] 在我用来创建 signedUrl 的代码之后:

func (s *GoogleStorage) Get(ctx context.Context, fileName string) (string, error) {
    url, err := storage.SignedURL(s.Config.BucketImagesName, fileName, &storage.SignedURLOptions{
        GoogleAccessID: s.Config.BucketServiceAccountDetails.ClientEmail,
        PrivateKey:     []byte(s.Config.BucketServiceAccountDetails.PrivateKey),
        Method:         http.MethodGet,
        Expires:        time.Now().Add(time.Second * 180),
    })
    if err != nil {
        return "", err
    }
    return url, nil
}

最佳答案

好吧,一觉醒来,我找到了答案。 结果发现,当json编码成字符串时,所有的特殊字符都被编码了。

示例:& -> \u0026

所以我在我的UT中测试的url有&,而api返回的url有\u0026,而google似乎没有相同的行为两种情况。

所以解决方案是禁用 HTML 转义:

encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
return encoder.Encode(response)

关于api - Google 存储桶签名 URL 403,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48571670/

相关文章:

node.js - Nodejs twitter api 不返回预期的 token

java - 用 Java 包装 Lua API

go - 使用 Go 从 PEM 格式的 Google "oauth2/v1/certs"证书中提取公钥

google-cloud-storage - 如何授予多个 appengine 项目访问同一个 Cloud Storage 存储桶的权限?

google-cloud-platform - 如何在不使用本地服务帐户 key 文件的情况下从 Cloud Run 服务访问 Google Cloud Storage 存储桶?

django-tastypie : why are api keys useful and how to support multiple auth schemes?

web-services - XML-RPC 是否不好用作公共(public) API 实现的协议(protocol)?

templates - FuncMap 的多个模板

go - 包中的某些函数显示为未定义的 Golang

google-cloud-platform - 有没有办法找到大于特定大小的 Google Cloud Storage Bucket 中的所有文件/对象?