amazon-s3pre-signed-url

How to add metadata to S3 Presigned url (PUT not POST) - Javascript SDK V3


Trying to add metadata to my presigned url. The url generates and has the metadata included in the query string, but I am not able to submit my file with the metadata as it fails with 403 forbidden. It should be noted that the url works fine if I remove the metadata from the setup. I have tried signing headers, unhoisting headers and nothing works. I know this is possible with presigned POST, but I need it to work for PUT.

Lambda code to generate URL:

    const params={
    Bucket: bucket,
    Key: key,
    Metadata:{
            "filesize": filesInfo.fileSize,
            "origfilename": encodeURIComponent(filesInfo.origFilename),
            "filetype": filesInfo.fileType,
    },
};
console.log("params=", params);
const headersToSign= new Set([
    // "ContentLength",
    "x-amz-meta-fileSize",
    "x-amz-meta-fileType",
    "x-amz-meta-origFilename",
]);
const unhoistableHeaders=new Set ([
    "x-amz-meta-fileSize", "x-amz-meta-fileType", "x-amz-meta-origFilename"
]);

const command=new PutObjectCommand(params);

const url = await getSignedUrl(s3Client, command, { 
    expiresIn: expiry,
    signedHeaders: headersToSign,
    unhoistableHeaders: unhoistableHeaders
});

Client fetch:

    const encodedFileName = encodeURIComponent(fileToSubmit.name);//did this to ensure filenames work--need to decode when showing file

const myHeaders = new Headers({
"x-amz-meta-filesize": fileToSubmit.size,
"x-amz-meta-filetype": fileToSubmit.type,
"x-amz-meta-origfilename": encodedFileName,
});

const myRequest = new Request(url, {
method: 'PUT',
mode: 'cors',
cache: 'default',
body: fileToSubmit, 
headers: myHeaders
});

fetch(myRequest)
.then(response => {
})
.then(data => {
})

Solution

  • Well that was silly. It works now. I just hadn't ensured that my metadata values were all strings. The filesize metadata was a number and once I converted it to a string in the lambda and added that value to the metadata all was well.