I’m trying to put a video file to my bucket using a pre-signed url in angular4.
Node:
let s3 = new AWS.S3();
s3.config.update({
accessKeyId: process.env.VIDEO_ACCESS_KEY,
secretAccessKey: process.env.VIDEO_SECRET_KEY
})
let videoId = await Video.createVideo()
let params = {
ACL: "public-read",
Bucket: process.env.BUCKET_NAME,
ContentType: 'video/mp4',
Expires: 100,
Key: req.jwt.username+"/"+videoId,
}
return s3.getSignedUrl('putObject', params, function (err, url) {
if(!err) {
console.log(url);
res.status(200);
res.json({
url: url,
reference: `${process.env.BUCKET_NAME}/${req.jwt.username}/${videoId}`,
acl: params.ACL,
bucket: params.Bucket,
key: params.Key,
contentType: params.ContentType,
});
} else {
console.log(err);
res.status(400);
res.json({
message: "Something went wrong"
})
}
});
This successfully generates a url for me, and I try to use it in my post request in the front end.
Angular:
this.auth.fileUpload().subscribe((result) => {
console.log(result["key"], result["acl"], result["bucket"], result["contentType"])
if(!result["message"]) {
let formData = new FormData();
formData.append('file', file.files[0]);
const httpOptions = {
headers: new HttpHeaders({
"Key": result["key"],
"ACL": result["acl"],
"Bucket": result["bucket"],
"Content-Type": result["contentType"],
})
};
this.http.post(result["url"], formData, httpOptions ).subscribe((response) => {
console.log("response");
console.log(response);
let reference = `https://s3.amazonaws.com/${result["reference"]}`
this.auth.makeVideo(result["reference"]).subscribe((result) => {
console.log(result);
});
}, (error) => {
console.log("error");
console.log(error);
})
But this generates an error.
SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your key and signing method
Here’s the URL that I generate
I’m pretty sure I’m just making a simple mistake, but I can’t figure it out for the life of me. Do I need to do something with my headers? Do I need to change the way I read the file for the post? I’ve gotten it to work with a public bucket with FormData and a simple post request with no headers, but now that I’m working with Policies and a private bucket, my understanding is much less. What am I doing wrong?
Solution:
If you generate a pre-signed URL for PutObject then you should use the HTTP PUT method to upload your file to that pre-signed URL. The POST method won’t work (it’s designed for browser uploads).
Also, don’t supply HTTP headers when you invoke the PUT. They should be supplied when generating the pre-signed URL, but not when using the pre-signed URL.