如何为Google Storage创建文件大小有限的签名URL?

xdnvmnnf  于 2023-06-27  发布在  Go
关注(0)|答案(3)|浏览(91)

我正在尝试创建一个签名的上传URL,以便客户端可以直接将文件上传到Google存储桶,我想防止用户上传大文件。因此,我想定义可以通过官方Go SDK的签名URL上传的最大文件大小。不幸的是,我找不到任何这样的例子。这是可能的吗?你会如何限制文件大小,让我们说1mb?

yqkkidmi

yqkkidmi1#

您正在查找storage.GenerateSignedPostPolicyV4,它允许您通过PostPolicyV4Options www.example.com设置策略文档https://cloud.google.com/storage/docs/authentication/signatures#policy-document

storage.GenerateSignedPostPolicyV4("my-bucket", "my-object.txt", &storage.PostPolicyV4Options{
        Conditions: []storage.PostPolicyV4Condition{
            storage.ConditionContentLengthRange(0, 1<<20),
        },
})
zi8p0yeb

zi8p0yeb2#

策略文档允许您更好地控制您在Cloud Storage上上传的对象,通过此功能,您可以控制每次上传必须满足的一系列条件。
由于你需要控制你需要上传的对象的大小,我建议你看一下这里的例子:

{"expiration": "2020-06-16T11:11:11Z",
 "conditions": [
  ["starts-with", "$key", ""],
  {"bucket": "travel-maps"},
  {"success_action_redirect": "http://www.example.com/success_notification.html"},
  ["eq", "$Content-Type", "image/jpeg"],
  ["content-length-range", 0, 1000000],
  {"x-goog-algorithm": "GOOG4-RSA-SHA256"},
  {"x-goog-credential": "example_account@example_project.iam.gserviceaccount.com/20191102/auto/storage/goog4_request"},
  {"x-goog-date": "20191102T043530Z"}
  ]
}

正如您所看到的,字段“content-length-range”,0,1000000]不允许文档大于1 Mb。

8gsdolmq

8gsdolmq3#

你必须使用GenerateSignedPostPolicyV4。这将从bucket、object和opts生成一个PostPolicyV4值。该策略允许您添加文件限制作为条件。

pv4, err := storage.GenerateSignedPostPolicyV4("my-bucket", "my-object.txt", &storage.PostPolicyV4Options{
        GoogleAccessID: "my-access-id",
        PrivateKey:     []byte("my-private-key"),

        // The upload expires in 2hours.
        Expires: time.Now().Add(2 * time.Hour),

        Fields: &storage.PolicyV4Fields{
            StatusCodeOnSuccess:    200,
            RedirectToURLOnSuccess: "https://example.org/",
            // It MUST only be a text file.
            ContentType: "text/plain",
        },

        // The conditions that the uploaded file will be expected to conform to.
        Conditions: []storage.PostPolicyV4Condition{
            // Make the file a maximum of 10mB.
            storage.ConditionContentLengthRange(0, 10<<20),
        },
    })

你可以点击这里找到更多的条件。
之后,您可以通过发送普通HTTP请求,使用生成的post策略上传文件。

formBuf := new(bytes.Buffer)
    mw := multipart.NewWriter(formBuf)
    for fieldName, value := range pv4.Fields {
        if err := mw.WriteField(fieldName, value); err != nil {
            // TODO: handle error.
        }
    }
    file := bytes.NewReader(bytes.Repeat([]byte("a"), 100))

    mf, err := mw.CreateFormFile("file", "myfile.txt")
    if err != nil {
        // TODO: handle error.
    }
    if _, err := io.Copy(mf, file); err != nil {
        // TODO: handle error.
    }
    if err := mw.Close(); err != nil {
        // TODO: handle error.
    }

    // Compose the request.
    req, err := http.NewRequest("POST", pv4.URL, formBuf)
    if err != nil {
        // TODO: handle error.
    }
    // Ensure the Content-Type is derived from the multipart writer.
    req.Header.Set("Content-Type", mw.FormDataContentType())
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        // TODO: handle error.
    }
    _ = res

示例代码可以在这里找到

相关问题