Google 存储桶 SignedUrls 403
Google bucket SignedUrls 403
我正在做一个简单的休息 API,它执行以下操作:
- 获取base64编码的图片
- 解码
- 将其存储在特定的 google 存储桶中
现在,在 GET 动词上,我的 api returns 一个已签名的 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 并尝试向邮递员发出 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 escaping:
encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
return encoder.Encode(response)
我正在做一个简单的休息 API,它执行以下操作:
- 获取base64编码的图片
- 解码
- 将其存储在特定的 google 存储桶中
现在,在 GET 动词上,我的 api returns 一个已签名的 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 并尝试向邮递员发出 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 escaping:
encoder := json.NewEncoder(w)
encoder.SetEscapeHTML(false)
return encoder.Encode(response)