Home  >  Article  >  Backend Development  >  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
Linda HamiltonOriginal
2024-11-24 00:45:14926browse

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/*"
        }
    ]
}

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" }
    ]
}

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
}

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!

Statement:
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