我正在尝试通过PUT接口将图像文件(jpeg)上传到AWS S3,我收到错误SignatureDoesNotMatch。
在我的服务器上,我有一个带有端点的Express node.js应用程序,用于创建签名网址。
'use strict';
const express = require('express');
const bodyParser = require('body-parser');
const config = require('./config');
// Load the AWS SDK for Node.js
const AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: config.AWS_ACCESS_KEY_ID,
secretAccessKey: config.AWS_SECRET_ACCESS_KEY,
region: 'us-east-1'
});
const s3 = new AWS.S3();
const app = express();
const awsS3Router = express.Router();
// parse application/json
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
// AWS S3 REST endpoints
awsS3Router.get('/getImageDrop', function(req, res) {
if(!req.query.filename) {
res.status(400).send('Request query is empty!');
}
const s3Params = {
Bucket: config.S3_BUCKET,
ContentType: 'image/jpeg',
ACL: 'public-read',
Key: req.query.filename,
Expires: 6000
};
s3.getSignedUrl('putObject', s3Params, function(err, data) {
if(err){
console.error('ERROR: ' + err);
return res.end();
}
const returnData = {
signedRequest: data,
url: 'https://' + config.S3_BUCKET + '.s3.amazonaws.com/' + req.query.filename
};
app.locals.s3SignedUrl = returnData.signedRequest;
res.write(JSON.stringify(returnData));
res.end();
});
});
app.use('/aws/s3', awsS3Router);
module.exports = app;

在客户端,我可以调用此端点并获取已签名的S3 URL。响应url格式为: https://[bucket姓名] .s3.amazonaws.com / 878CF5A4-D013-435F-BF7D-F45AB69E580F.jpg?AWSAccessKeyId = [AWS访问密钥]& Content-Type = image%2Fjpeg& Expires = 1521244920& Signature = [签名]&安培; X-AMZ-ACL =公共读
客户端代码具有将文件上载到签名的S3 URL的功能。
async uploadImageToS3BucketAsync(imageFileUri, fileSize, signedUrl) {
const fileName = PathParse(imageFileUri).base;
let form = new FormData();
form.append('files[0]', {
'uri': imageFileUri,
'name': fileName,
'type': 'image/jpeg'
});
//form.append('photo', imageFileUri);
console.info('INFO: PUT ' + signedUrl.signedRequest + ': Request: ' + JSON.stringify(form));
return fetch((signedUrl.signedRequest), {
method: 'PUT',
headers: { 'Content-Type': 'image/jpeg', 'Content-Length': fileSize },
body: form
})
.then(function(res) {
if (res.ok) {
console.info('INFO: PUT ' + JSON.stringify(signedUrl) + ': Response: ' + JSON.stringify(res));
return res.json();
} else {
console.error('Failed to upload image to S3 bucket!');
console.error('ERROR: ' + JSON.stringify(res));
alert('Failed to upload image to S3 bucket!!');
}
})
.catch(function(err) {
console.error('ERROR: Request failed', err);
});
}

不幸的是,上传系统失败,出现403错误:
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
&#13;
我猜我在PUT调用的请求标头中遗漏了一些内容,但我不确定它是什么。有没有人在node.js找到解决方案?