duanlu1793 2018-02-01 21:03
浏览 48
已采纳

Google存储桶SignedUrls 403

I'm doing a simple rest API which does the following:

  • get base64 encoded image
  • decode it
  • stores it on on specific google bucket

Now, on the GET verb, my api returns a signed url targeting the bucket image.

I've coded a test that works:

    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())
    })

But when I run the .exe and try to make ssome request with postman, I get a 403 error in the signed url:

<?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>

Any ideas ? I really don't understand... Save me guys

[EDIT] Here after the code I use to create 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条回答 默认 最新

  • donglong9745 2018-02-02 08:02
    关注

    Ok, after I woke up, I found the answer. It turns out that when the json is marshalized into string, all the special characters are encoded.

    Example: & -> \u0026

    So the url I tested in my UT had &, while the url returned by the api had \u0026, and google does not seem to have the same behaviour on both cases.

    So the solution is to disable HTML escaping:

    encoder := json.NewEncoder(w)
    encoder.SetEscapeHTML(false)
    return encoder.Encode(response)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 nslt的可用模型,或者其他可以进行推理的现有模型
  • ¥15 arduino上连sim900a实现连接mqtt服务器
  • ¥15 vncviewer7.0安装后如何正确注册License许可证,激活使用
  • ¥15 phython如何实现以下功能?查找同一用户名的消费金额合并2
  • ¥66 关于人体营养与饮食规划的线性规划模型
  • ¥15 基于深度学习的快递面单识别系统
  • ¥15 Multisim仿真设计地铁到站提醒电路
  • ¥15 怎么用一个500W电源给5台60W的电脑供电
  • ¥15 请推荐一个轻量级规则引擎,配合流程引擎使用,规则引擎负责判断出符合规则的流程引擎模板id
  • ¥15 Excel表只有年月怎么计算年龄