首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Go中做一个预先签名的上传到AWS S3?

如何在Go中做一个预先签名的上传到AWS S3?
EN

Stack Overflow用户
提问于 2015-09-03 14:00:13
回答 4查看 8.9K关注 0票数 3

我想做一个预签名的POST将文件上载到AWS S3桶 -该怎么做呢?

请注意,这是不一样的预先签署上传与PUT。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-09-08 09:10:47

因此,为了帮助其他人,我将自己回答这个问题,并提供一些代码来帮助其他可能有同样问题的人。

例如,Google的web应用程序呈现一个预先签名的POST表单,可以找到这里

我在Go中创建了一个做预先签名的帖子的小型图书馆。

简而言之,对公共阅读的亚马逊S3桶进行预先签名的帖子,您需要:

1.将S3桶配置为只允许公开下载.

仅允许公开读取的桶策略示例。

代码语言:javascript
运行
复制
{
    "Version": "2012-10-17",
    "Id": "akjsdhakshfjlashdf",
    "Statement": [
        {
            "Sid": "kjahsdkajhsdkjasda",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::BUCKETNAMEHERE/*"
        }
    ]
}

2.为HTTP创建允许上传.的策略

AWS S3文档

例如,POST策略模板过期,以上传特定的密钥,进入特定的桶并允许公共读取访问。

代码语言:javascript
运行
复制
{ "expiration": "%s",
    "conditions": [
        {"bucket": "%s"},
        ["starts-with", "$key", "%s"],
        {"acl": "public-read"},

        {"x-amz-credential": "%s"},
        {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
        {"x-amz-date": "%s" }
    ]
}

3.使用S3桶所有者的凭据生成和签名策略。

AWS博士

  • 填写过期、桶、键、凭据和日期的正确值。
  • base64对策略进行编码。
  • HMAC- the 256的策略得到一个签名。
  • 十六进制编码签名。

4.构造和发布多部分表单数据

AWS S3文档

现在,您可以生成一个HTML表单并自动获得正确的多部分表单数据请求,如上面的链接所述。

我想亲手做这个,所以这里是怎么做的。

无论哪种方式,您都需要提供在步骤2和步骤3中创建的POST策略中指定的所有部分。除了强制字段(不在策略中)之外,您还不能在请求中添加其他字段。

还指定了字段的顺序,所有字段都是HTTP请求中的多部分字段。

代码语言:javascript
运行
复制
func Upload(url string, fields Fields) error {
    var b bytes.Buffer
    w := multipart.NewWriter(&b)
    for _, f := range fields {
            fw, err := w.CreateFormField(f.Key)
            if err != nil {
                    return err
            }
            if _, err := fw.Write([]byte(f.Value)); err != nil {
                    return err
            }
    }
    w.Close()

    req, err := http.NewRequest("POST", url, &b)
    if err != nil {
            return err
    }
    req.Header.Set("Content-Type", w.FormDataContentType())

    client := &http.Client{}
    res, err := client.Do(req)
    if err != nil {
            return err
    }
    if res.StatusCode != http.StatusOK {
            err = fmt.Errorf("bad status: %s", res.Status)
    }
    return nil
}
票数 5
EN

Stack Overflow用户

发布于 2015-11-07 00:38:56

下面是来自https://github.com/minio/minio-go的另一种方法,您可能希望使用一种完整的编程方式来生成预先签名的post策略。

代码语言:javascript
运行
复制
package main

import (
    "fmt"
    "log"
    "time"

    "github.com/minio/minio-go"
)

func main() {
    policy := minio.NewPostPolicy()
    policy.SetKey("myobject")
    policy.SetBucket("mybucket")
    policy.SetExpires(time.Now().UTC().AddDate(0, 0, 10)) // expires in 10 days
    config := minio.Config{
        AccessKeyID:     "YOUR-ACCESS-KEY-HERE",
        SecretAccessKey: "YOUR-PASSWORD-HERE",
        Endpoint:        "https://s3.amazonaws.com",
    }
    s3Client, err := minio.New(config)
    if err != nil {
        log.Fatalln(err)
    }
    m, err := s3Client.PresignedPostPolicy(policy)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("curl ")
    for k, v := range m {
        fmt.Printf("-F %s=%s ", k, v)
    }
    fmt.Printf("-F file=@/etc/bashrc ")
    fmt.Printf(config.Endpoint + "/mybucket\n")
}

步骤1:

代码语言:javascript
运行
复制
    policy := minio.NewPostPolicy()
    policy.SetKey("myobject")
    policy.SetBucket("mybucket")
    policy.SetExpires(time.Now().UTC().AddDate(0, 0, 10)) // expires in 10 days

实例化一个新的策略结构,此策略结构实现以下方法。

代码语言:javascript
运行
复制
func NewPostPolicy() *PostPolicy
func (p *PostPolicy) SetBucket(bucket string) error
func (p *PostPolicy) SetContentLength(min, max int) error
func (p *PostPolicy) SetContentType(contentType string) error
func (p *PostPolicy) SetExpires(t time.Time) error
func (p *PostPolicy) SetKey(key string) error
func (p *PostPolicy) SetKeyStartsWith(keyStartsWith string) error
func (p PostPolicy) String() string

第2步:

代码语言:javascript
运行
复制
    m, err := s3Client.PresignedPostPolicy(policy)
    if err != nil {
        fmt.Println(err)
        return
    }

现在,PresignedPostPolicy()获取PostPolicy结构并返回一个“key/value”的映射,该映射可以在HTML或curl命令中使用,以将数据上传到s3。

票数 4
EN

Stack Overflow用户

发布于 2015-09-05 01:39:00

乍一看,它看起来像POST与附加的策略和签名一起工作--专为基于浏览器的上传而设计。见AWS文档获取详细信息

具体来说,您需要生成一个策略并签署 --然后将它们包括在HTML中,从而包含POST请求--以及其他所需的信息。或者让浏览器帮你做。

在HTML表单POST上传的情况下,您只需要对策略字符串进行签名。要发布的最终网址可以根据表单内容:https://bucket.s3.amazonaws.com/<depends-on-form-content>而变化。所以你不能先签那个URL,因为你不知道它是什么。

这与您将文件放入的签名URL不同。您可以签名,因为您知道完整的URL:https://bucket.s3.amazonaws.com/known-key

您可以使用适当的策略和参数构建POST请求,并通过POST方式上传。但是,您需要事先知道表单的内容,才能知道URL。在这种情况下,您还可以使用一个预先签名的PUT URL。

至少乍一看就是这样.

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32377782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档