Home  >  Article  >  Backend Development  >  How to Implement Pre-Signed POST File Uploads to AWS S3 Using Go?

How to Implement Pre-Signed POST File Uploads to AWS S3 Using Go?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-21 22:30:13943browse

How to Implement Pre-Signed POST File Uploads to AWS S3 Using Go?

Pre-Signed POST Upload to AWS S3 Using Go

For secure file upload to AWS S3 buckets, pre-signed POST offers a convenient approach. Here's how to accomplish this in Go:

1. Configure Bucket Access:

Modify your S3 bucket's policy to allow public download:

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

2. Create Pre-Signed POST Policy:

Craft an HTTP POST policy that grants upload permission:

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

Configure the policy with these parameters:

  • expiration: Upload expiration time
  • bucket: Target S3 bucket name
  • key: Name of the file to be uploaded
  • credentials: Your AWS credentials
  • date: Current date

3. Sign Policy:

Use the S3 bucket owner's credentials to sign the policy:

  • Encode the policy using base64
  • Compute the HMAC-SHA256 signature
  • Encode the signature as a hexadecimal string

4. Construct POST Request:

Generate the multipart form data request:

import "github.com/aws/aws-sdk-go/aws/credentials"

type Field struct {
    Key, Value string
}

func Upload(url string, fields []Field) error {
    b := new(bytes.Buffer)
    w := multipart.NewWriter(b)
    for _, field := range fields {
        fw, err := w.CreateFormField(field.Key)
        if err != nil {
            return err
        }
        if _, err := fw.Write([]byte(field.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())

    creds := &credentials.StaticProvider{Value: credentials.Value{
        AccessKeyID:     "AKIAIOSFODNN7EXAMPLE",
        SecretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    }}
    cfg := &aws.Config{Credentials: creds}

    client := new(&http.Client{Transport: &aws.HTTPSHandler{Client: *client, Config: *cfg}})
    res, err := client.Do(req)
    if err != nil {
        return err
    }
    if res.StatusCode != http.StatusOK {
        return fmt.Errorf("bad status: %s", res.Status)
    }
    return nil
}

Provide the signed policy fields and the endpoint URL. Your pre-signed POST upload to AWS S3 will then be executed.

The above is the detailed content of How to Implement Pre-Signed POST File Uploads to AWS S3 Using 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