谷歌桶SignedUrls 403

时间:2018-02-01 21:03:49

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

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

  • 获取base64编码图像
  • 解码
  • 将其存储在特定的Google存储桶中

现在,在GET动词上,我的api返回一个针对存储桶图像的签名网址。

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

    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并尝试使用邮递员发出ssome请求时,我在签名网址中收到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
}

1 个答案:

答案 0 :(得分:2)

好的,我醒来后,我找到了答案。 事实证明,当json被编组为字符串时,所有特殊字符都被编码。

示例:& - &gt; \u0026

因此,我在我的UT中测试的网址为&,而api返回的网址为\u0026,而谷歌似乎在两种情况下都没有相同的行为。

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

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