无法用s3 getSignedUrl('getObject ..)下载图像并返回Signature不匹配

我对AWS比较陌生。 所有我试图做的是从我的应用程序上传图像到aws S3,并下载它在应用程序的另一个页面查看图像。 上传成功,并能够在S3中看到上传的图像。 但无法下载,因为它会引发以下错误。

FileTransferError {body = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>AKXXXXXXXXXXXXXXXXXX</AWSAccessKeyId> <StringToSign>GET\n\n\n1469897687\n/huntuploads/uploads/%25222a85a6675d15eeeca5c8b da6eed4c52e%2522</StringToSign> <SignatureProvided>cUBhtiA5AGJbj8vl%2FX6xi%2B9BBRY%3D</SignatureProvided> <StringToSignBytes>47 45 54 0a 0a 0a 31 34 36 39 38 39 37 36 38 37 0a 2f 68 75 6e 74 66 6f 6f 64 75 70 6c 6f 61 64 73 2f 75 70 6c 6f 61 64 73 2f 25 32 35 32 32 32 61 38 35 61 36 36 37 35 64 31 35 65 65 65 63 61 35 63 38 62 64 61 36 65 65 64 34 63 35 32 65 25 32 35 32 32</StringToSignBytes> <RequestId>CCB513320456EB6B</RequestId> <HostId>v4c7Ozf911tErWo5dCsL9RNLL78r3rUE6234Z801ZFXuELrji4juDehHmaxnK8t5qMBGcjz90a I=</HostId></Error>"; code = 3; "http_status" = 403; source = "https://huntuploads.s3-us-west- 2.amazonaws.com/uploads/%25222a85a6675d15eeeca5c8bda6eed4c52e%2522? AWSAccessKeyId=AKXXXXXXXXXXXXXXXXXX&Expires=1469897687&Signature=cUBhtiA5AGJbj8vl% 252FX6xi%252B9BBRY%253D"; target = "file:///var/mobile/Containers/Data/Application/1EB46B25-8BC5- 46C9-BE6B-BF1E120B7627/Documents/%222a85a6675d15eeeca5c8bda6eed4c52e%22"; } 

以下是上传可在服务器端正常工作的图像的代码

  var AWS = require('aws-sdk'); AWS.config.update({accessKeyId: 'AXXXXXXXXX......', secretAccessKey: 'XXXXX....'}); AWS.config.update({region: 'us-west-2'}); var s3 = new AWS.S3( { params: {Bucket: 'huntfooduploads'}}); app.post('/FileUpload', function(req, res, next) { var fileStream = fs.createReadStream(req.files.file.path); var params = { 'Key': 'uploads/' + req.files.file.name, 'Body': fileStream, 'ContentEncoding': 'base64', 'Content-Type ': 'image/jpeg' }; s3.upload(params, function(err, data) { if (err) throw err; console.log('after s3 upload====', err, data); var imgFileInfo = req.files; var imgUploadData = data; .... } } 

以下代码用于从服务器端使用getSignedUrl为s3下载图像

 var urlParams = {Bucket: 'huntuploads', Key:'uploads/'+rows[0].MyHunt_FileName}; // s3 getSigned Url s3.getSignedUrl('getObject', urlParams, function(err, url) { if (err) throw callback(err); var fullUrl={awsUrl:url}; res.send(fullUrl); }) 

一旦我发送fullUrl回到客户端,这是应用程序,我试着使用以下

 $cordovaFileTransfer.download(encodeURI(itemData[3].awsUrl), targetPath, options, trustHosts) .then(function(result) { console.log('Success! Download is successful'); $scope.imgURI = targetPath; }, function(err) { console.log('Error!!! Download is not successful'); // Error }, function (progress) { $timeout(function () { $scope.downloadProgress = (progress.loaded / progress.total) * 100; }); }); 

从应用程序的一面,当我试图下载图像,我收到上面提到的消息。 我尝试添加nx-amz-server-side-encryption-customer-algorithm:AES256作为头文件。 我需要知道以下

  1. 这是正确的方法将数据从服务器传递到客户端(应用程序)
  2. 如果getSigned url的urlParams是正确的。 不知道如果我错过了什么或什么可以做。

有人能告诉我正确的方向吗?

那么我已经解决了我的自我。 但是,谢谢你的帮助迈克尔和其他人。 解决方法是我添加了下面的行作为选项之一

var options = {encodeURI:false}; 然后cordovaFileTransfer.download(encodeURI(itemData [3] .awsUrl),targetPath,options,trustHosts){…}

解决了这个问题。 看起来像encodeUI设置为默认情况下,改变了签名。

据我所知,getSignedUrl函数不检查文件是否存在,

1-确保您的文件的URL是正确的(没有签名的URL)。

2-确保许可和访问您的存储桶是正确的

最后,当你调用getSignedUrl函数时,检查你机器的date和时间。