AWS分段上传SignatureDoesNotMatch

时间:2020-04-06 15:09:59

标签: node.js amazon-web-services mpu

我正在尝试使用分段上传将PDF文件上传到AWS S3。但是,当我发送PUT请求以上传零件时,我收到一个SignatureDoesNotMatch错误。

<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>

我的服务器代码(节点)如下:

CREATE MultiPart Upload

const AWS = require('aws-sdk');

AWS.config.region = 'us-east-1';
const s3 = new AWS.S3({ apiVersion: '2006-03-01' });

const s3Params = {
      Bucket: 'bucket-name',
      Key: 'upload-location/filename.pdf',
    }

const createRequest = await s3.createMultipartUpload({
          ...s3Params
          ContentType: 'application/pdf'
        }).promise(); 

GET Signed URL

let getSignedUrlParams = {
      Bucket: 'bucket-name',
      Key: 'upload-location/filename.pdf',
      PartNumber: 1,
      UploadId: 'uploadId',
      Expires: 10 * 60
    }

const signedUrl = await s3.getSignedUrl('uploadPart',getSignedUrlParams);

并且客户端代码(在JS中)是:

const response = await axios.put(signedUrl, chunkedFile, {headers: {'Content-Type':'application-pdf'}});

一些注意事项:

  1. 当我允许所有公共访问存储桶时,此代码有效。但是,如果所有公共访问均被阻止,则该代码将无效。
  2. 在所有公共访问都被阻止的情况下,我仍然可以使用aws cli使用相同的凭据上传到存储桶。
  3. 我已经尝试过重新生成AWS Access Key ID和Secret Access Key,但这没有帮助。

无法找出问题所在。任何帮助,将不胜感激。

PS:这是我在这里发布的第一个问题。因此,如果我没有适当地张贴它,请原谅我。让我知道是否需要更多详细信息。

3 个答案:

答案 0 :(得分:0)

尝试类似的方法,对我有用。

var fileName = 'your.pdf';
var filePath = './' + fileName;
var fileKey = fileName;
var buffer = fs.readFileSync('./' + filePath);
// S3 Upload options
var bucket = 'loctest';

// Upload
var startTime = new Date();
var partNum = 0;
var partSize = 1024 * 1024 * 5; // Minimum 5MB per chunk (except the last part) http://docs.aws.amazon.com/AmazonS3/latest/API/mpUploadComplete.html
var numPartsLeft = Math.ceil(buffer.length / partSize);
var maxUploadTries = 3;
var multiPartParams = {
    Bucket: bucket,
    Key: fileKey,
    ContentType: 'application/pdf'
};
var multipartMap = {
    Parts: []
};

function completeMultipartUpload(s3, doneParams) {
  s3.completeMultipartUpload(doneParams, function(err, data) {
    if (err) {
      console.log("An error occurred while completing the multipart upload");
      console.log(err);
    } else {
      var delta = (new Date() - startTime) / 1000;
      console.log('Completed upload in', delta, 'seconds');
      console.log('Final upload data:', data);
    }
  });
}

如果上传失败,您将收到错误消息。如果您打印出

的结果,我们可以帮助您解决这个问题
console.log(this.httpResponse)

console.log(this.request.httpRequest)

答案 1 :(得分:0)

对我有用的是签名的版本。在初始化S3时,还应提及签名版本。

const s3 = new AWS.S3({ apiVersion: '2006-03-01', signatureVersion: 'v4' });

答案 2 :(得分:0)

Content-Part调用中删除axios标头。

const response = await axios.put(signedUrl, chunkedFile);

仅添加一部分时,实际上并没有上传完整的文件,因此内容类型不是application-pdf

这与对整个对象进行PUT不同。

相关问题