I'm generating an AWS S3 presigned post object on my server using
. I'm then trying to upload a file directly to the S3 bucket from the client using fetch using the presigned post url & fields, but am getting a s3.createPresignedPost()
403 Forbidden
.
I've tried manually adding form fields to my FormData object to directly match this example: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html but continue to receive the 403 error.
Server-side function for generating the post object
const AWS = require("aws-sdk/global"); const S3 = require("aws-sdk/clients/s3"); const uuidv4 = require("uuid/v4"); AWS.config.update({ accessKeyId: process.env.S3_KEY_ID, secretAccessKey: process.env.S3_SECRET_KEY, region: "us-east-1" }); const s3 = new S3(); const getPresignedPostData = (bucket, directory) => { const key = `${directory}/${uuidv4()}`; const postData = s3.createPresignedPost({ Bucket: bucket, Fields: { Key: key, success_action_status: "201" }, Conditions: [{ acl: "public-read" }], ContentType: "image/*", Expires: 300 }); return postData; };
Returns something that looks like:
{ fields: { Key: "5cd880a7f8b0480b11b9940c/86d5552b-b713-4023-9363-a9b36130a03f" Policy: {Base64-encoded policy string} X-Amz-Algorithm: "AWS-HMAC-SHA256" X-Amz-Credential: "AKIAI4ELUSI2XMHFKZOQ/20190524/us-east-1/s3/aws4_request" X-Amz-Date: "20190524T200217Z" X-Amz-Signature: "2931634e9afd76d0a50908538798b9c103e6adf067ba4e60b5b54f90cda49ce3" bucket: "picture-perfect-photos" success_action_status: "201" }, url: "https://s3.amazonaws.com/picture-perfect-photos" }
My client side function looks like:
const uploadToS3 = async ({ fields, url }, file) => { const formData = new FormData(); Object.keys(fields).forEach(key => formData.append(key, fields[key])); formData.append("file", file); try { const config = { method: "POST", body: formData }; const response = await fetch(url, config); if (!response.ok) { throw new Error(response.statusText); } const data = await response.json(); return data; } catch (err) { console.log(err.message); } };
And my S3 bucket CORS config is as follows:
<?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration>
I expect to get the XML document that is sent when success_action_status: "201"
is set, but am continually getting 403 Forbidden