Home > Backend Development > Golang > How to Implement Pre-signed POST Uploads to AWS S3 in Go?

How to Implement Pre-signed POST Uploads to AWS S3 in Go?

Linda Hamilton
Release: 2024-11-24 00:45:14
Original
995 people have browsed it

How to Implement Pre-signed POST Uploads to AWS S3 in Go?

Pre-signed POST Upload to AWS S3 in Go: A Comprehensive Guide

Background

Pre-signed POST uploads allow unauthorized users to securely upload files to an S3 bucket. Unlike pre-signed PUT, this method relies on policy-based authorization and simplifies file transfers.

Steps for Pre-signed POST Upload

1. Configure Public-Read Access for the S3 Bucket:

Set the following bucket policy to enable public read access:

{
    "Version": "2012-10-17",
    "Id": "akjsdhakshfjlashdf",
    "Statement": [
        {
            "Sid": "kjahsdkajhsdkjasda",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::BUCKETNAMEHERE/*"
        }
    ]
}
Copy after login

2. Generate POST Policy:

Create a POST policy template, fill in key fields (expiration, bucket, key, credentials, date), and encode it:

{ "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" }
    ]
}
Copy after login

3. Sign the Policy:

Use S3 bucket owner's credentials to generate the signature:

  • Fill in the policy values.
  • Base64 encode the policy.
  • HMAC-SHA256 the policy.
  • Hex encode the signature.

4. Construct Multipart Form Data:

Include all policy parameters in the multipart form data:

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
}
Copy after login

Resources

  • [AWS S3 Docs: Pre-signed POST](https://docs.aws.amazon.com/AmazonS3/latest/userguide/post-object.html)
  • [GitHub: Pre-signed POST library for Go](https://github.com/danlami/presigned-post/tree/main/pkg/presigned)

The above is the detailed content of How to Implement Pre-signed POST Uploads to AWS S3 in Go?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template