I've been following many many threads online regarding how to properly get a presigned url from a lambda backend and then use it in React with Axios to upload an image to s3, but I just cant seem to get it to work. Here are some threads i followed:
- https://bobbyhadz.com/blog/aws-s3-presigned-url-react
- AWS S3 presigned url with React uploads empty file
- How to upload image to amazon aws S3 using presigned Url
- Call S3 pre-signed URL with postman
I am either getting a 403 error (from axios.post), or Access denied (in Postman).
Here is my lambda code:
def getPresignedUrl(objName, contentType, fields=None, conditions=None, expiration=300):
# Generate a presigned S3 POST URL
s3_client = boto3.client("s3")
try:
response = s3_client.generate_presigned_url(
"put_object",
{
"Bucket": os.environ["S3_BUCKET_NAME"],
"Key": objName,
"ContentType": contentType,
},
300,
)
except ClientError as e:
logger.error("Error generating presigned url for s3: %s" % (e))
raise
except:
logger.error("Unexpected error generating presigned url for s3!")
# The response contains the presigned URL and required fields
return response
Here is my frontend upload code:
const uploadImageToServer = (file) => {
return new Promise(async (resolve) => {
const obj = {
objName: file.name,
contentType: file.type,
};
let response = await axiosInstance.post("/getsignedurl", obj);
console.log(response.data);
const requestOptions = {
method: "PUT",
headers: {
"Content-Type": file.type,
},
body: file,
};
const resp = await fetch(response.data, requestOptions);
console.log(resp);
With the above code, I am getting the following error after making the fetch request:
{
ok: false
redirected: false
status: 403
statusText: "Forbidden"
type: "cors",
url: "wwww.presignedurl.com"
}
Any ideas for this? Public access is blocked on my s3 buckets, but that shouldn't matter if i'm using a presigned url right? Do i need to enable "private" ACL or "public-read" ACL?
Edit updated code
all public access is blocked.. and yet you are trying to create a publicly available object. (I see you did edit the question). Does the issue prevails for private objects too? When you get a presigned url, can you put an object outside your app? (curl, postman,..)?403 error. presigned urls should still allow uploads to a private bucket... so i'm not suer whats wrong