简体   繁体   中英

AWS S3 Browser-Based Uploads Using POST (AWS4) and fetch

I'm trying to use fetch to POST upload a file (via FormData ) to an S3 bucket.

I'm using aws4-signature to create the policy signature.

I'm using "Creating a POST policy" and "Browser-Based Uploads Using POST" as guides.


Signature

I know 100% that my ACCESS_KEY and SECRET are correct.

The date created below is the same one used for x-amz-date and x-amz-credential .

const aws4_sign = require("aws4-signature");

const date = new Date();
const signature = aws4_sign(SECRET, date, "us-west-2", "s3", BASE64_POLICY);

HTTPS Request

const url = "https://s3-us-west-2.amazonaws.com/example-bucket";

const data = {
  "AWSAccessKeyId": "ACCESS_KEY",
  "key": "photos/7bf0b615-badc-4f57-8320-71f7e690554e.png",
  "acl": "public-read",
  "policy": "BASE64_POLICY",
  "signature": "POLICY_SIGNATURE",
  "content-type": "image/png",
  "x-amz-algorithm": "AWS4-HMAC-SHA256",
  "x-amz-credential": "ACCESS_KEY/20170119/us-west-2/s3/aws4_request",
  "x-amz-date": "20170119T165423Z",
};

const policy = JSON.parse(window.atob(data.policy));
// {
//   "expiration": "2017-01-19T17:24:23.090Z",
//   "conditions": [
//     { "key": "photos/7bf0b615-badc-4f57-8320-71f7e690554e.png" },
//     { "bucket": "example-bucket" },
//     { "acl": "public-read" },
//     [ "starts-with", "$Content-Type", "image/png" ],
//     [ "starts-with", "$Content-Length", "" ],
//     [ "content-length-range", 1, 10000000 ],
//     { "x-amz-algorithm": "AWS4-HMAC-SHA256" },
//     { "x-amz-server-side-algorithm": "AES256" },
//     { "x-amz-storage-class": "STANDARD" },
//     { "x-amz-date": "20170119T165423Z" },
//     { "x-amz-credential": "ACCESS_KEY/20170119/us-west-2/s3/aws4_request" }
//   ]
// }

const body = new FormData();
for (const key in data) {
  body.append(key, data[key]);
}

const promise = fetch(url, {method: 'POST', body});

XML Response

<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>SignatureDoesNotMatch</Code>
  <Message>The request signature we calculated does not match the signature you provided.
    Check your key and signing method.</Message>
  <AWSAccessKeyId>ACCESS_KEY</AWSAccessKeyId>
  <StringToSign>BASE64_POLICY</StringToSign>
  <SignatureProvided>POLICY_SIGNATURE</SignatureProvided>
  <StringToSignBytes>65 79 4a 6c 65 48 42 70 63 6d 46 30 61 57 39 75 49 6a 6f 69 4d 6a ... </StringToSignBytes>
  <RequestId>C0AE9240D8991EEF</RequestId>
  <HostId>Zih68OHYod6c3HX8ecVNXCU1Iz/ek0UGEh9Xwb5TBNlS7IQUZjdofNRqk/Kl9Rdq3rNkRhNxj9s=</HostId>
</Error>

Try removing

"AWSAccessKeyId": "ACCESS_KEY",

As per the documentation here http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

There is no AWSAccessKeyId For a signature v4.

AWSAccessKeyId is for signature v2.

Providing it will cause s3 to think you are using signature v2. And there is no X-Amz-Credential In signature v2.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM