问题
I am trying to upload a video to s3 and have a pre-signed PUT url. The following is the code to do so.
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {MediaCapture} from 'ionic-native';
import {Http} from '@angular/http';
import { Transfer } from 'ionic-native';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public base64Image: string;
constructor(private navController: NavController, public http: Http) {
this.base64Image = "https://placehold.it/150x150";
}
public takeVideo() {
MediaCapture.captureVideo({limit:2}).then(function(videoData){
var link = "https://mysamplebucket.s3.amazonaws.com/non-tp/esx.mov?AWSAccessKeyId=TEMP_KEYY&Expires=1482290587&Signature=JUIHHI%2FcnLkqSVg%3D&x-amz-security-token=FQoDYXDGRfTXk6hma0Rxew6yraAX%2FlYGaQmYLwkvsuuB3%2F%2FtPvGDVs3dIQG0Ty3MeMjn0p%%26djt5xhAMk73pndJbZP0tCYYlvPvlUAyL8x7O%%2B3AwEa%%2B9b43yarIuPLCvujmKLTDyi%%3D%3Di";
var options: any;
options = {
fileKey: 'file',
fileName: 'esx.mov',
httpMethod: 'PUT',
chunkedMode: false,
mimeType: 'video/quicktime',
encodeURI: false,
headers: {
'Content-Type': 'video/quicktime'
}
};
var ft = new Transfer();
ft.upload(videoData[0].fullPath, link, options, false)
.then((result: any) => {
this.success(result);
}).catch((error: any) => {
this.failed(error);
});
}, function(err){
alert(err);
});
}
}
Here is the code that generates the pre-signed PUT url.
var params = {Bucket: s3_bucket, Key: filename, Expires: 900000};
var url = {
'url' : s3.getSignedUrl('putObject', params)
};
I get, SignatureDoesNotMatch
error. The message says, The request signature we calculated does not match the signature you provided. Check your key and signing method.
I am not sure what I am doing wrong here - I looked a few other SO and Ionic questions and tried what they recommended to no avail. Any ideas on what I and doing wrong?
回答1:
Your upload PUT
request will have a Content-Type: video/quicktime
header.
When the Content-Type
header is present in the request (not the response), its value is a non-optional component in the Signature V2 canonical request... which means you have to pass it to the code generating the signature.
var params = {Bucket: s3_bucket, Key: filename, Expires: 900000};
also needs this string (video/quicktime
, in this case) passed to it as ContentType: ...
for a PUT
request (but not for a GET
request, since this describes the content you are sending, and GET
requests customarily send no actual content.
The SDK documentation doesn't seem to specifically mention this, but it is most definitely required by S3.
回答2:
In case someone else is looking at this and is in a similar situation as me, I got a similar SignatureDoesNotMatchError when my s3 bucket's CORS Configuration did not contain <AllowedHeader>*</AllowedHeader>
I ran into this when moving from one bucket to another, copying all the settings except for the CORS Configuration.
来源:https://stackoverflow.com/questions/41078440/signaturedoesnotmatch-error-when-uploading-to-s3-via-a-pre-signed-url-using-ioni