s3”;签名不't匹配”;客户端发布jquery文件上传
s3 "signature doesn't match" client side post jquery-file-upload
我正在生成一个签名,用于在后端的节点中向s3进行客户端发布,并通过客户端上传jquery文件提交。我的签名生成如下所示:
app.post('/api/v1/s3', function(req, res){
var data = utils.getReqJson(req.body);
var mime_type = mime.lookup(data.filename);
var expire = moment().utc().add('hour', 1).toJSON("YYYY-MM-DDTHH:mm:ss Z");
var policy = JSON.stringify({
"expiration": expire,
"conditions": [
{"bucket": aws_bucket},
["starts-with", "$key", aws_bucket_dir],
{"acl": "private"},
{"success_action_status": "201"},
["starts-with", "$Content-Type", ''],
["content-length-range", 0, max_filesize]
]
});
var base64policy = new Buffer(policy).toString('base64');
var signature = crypto.createHmac('sha1', process.env.AWS_SECRET).update(base64policy).digest('base64');
signature = encodeURIComponent(signature.trim());
signature = signature.replace('%2B','+');
var file_key = uuid.v4();
res.json({ policy: base64policy,
signature: signature,
key: aws_bucket_dir + file_key + "_" + data.filename,
contentType: mime_type,
aws_access: process.env.AWS_ACCESS_KEY,
bucket_dir: aws_bucket_dir,
bucket: aws_bucket
});
});
然后在前端我有以下代码:
this.$().fileupload({
dataType: 'json',
type: 'POST',
autoUpload: true,
add: function (e, data) {
$.ajax({
url: window.ENV.api_url+'/' + window.ENV.api_namespace + '/s3',
type: 'POST',
dataType: 'json',
data: {
"filename": data.files[0].name
},
async: false,
success: function(retdata) {
//do actual upload stuff now.
data.url = 'https://'+retdata.bucket+'.s3.amazonaws.com/';
data.formData = {
key: retdata.key,
AWSAccessKeyId: retdata.aws_access,
acl: 'private',
policy: retdata.policy,
signature: retdata.signature,
success_action_status: 201,
"Content-Type": retdata.contentType
};
data.submit()
.success(function (result, textStatus, jqXHR) {
console.log('Success: ' + result);
})
.error(function (jqXHR, textStatus, errorThrown) {
console.log('Error: ' + errorThrown);
console.log(jqXHR);
console.log('Status: ' + textStatus);
});
console.log(retdata);
},
error: function (xhr, ajaxOptions, thrownError) {
console.log('AJAX: ' + xhr);
console.log('AJAX: ' + thrownError);
}
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css(
'width',
progress + '%'
);
}
});
我似乎提交了正确的表单数据来匹配我的签名生成,但每次尝试提交时都会出现以下错误:
SignatureDoesNotMatch-我们计算的请求签名与您提供的签名不匹配。检查您的密钥和签名方法
我正在努力弄清楚我可能做错了什么,如果有人能帮我,我将不胜感激。
我为此挣扎了一段时间,最终使用以下方法使其正常工作:
在s3处理程序中:
var uploadToS3 = function(s3Url, cb){
var fd = new FormData();
var file = document.getElementById('file').files[0];
var key = 'uploads'/' + file.name;
fd.append('key', 'uploads'/' + file.name);
fd.append('acl', 'public-read');
fd.append('Content-Type', 'multipart/form-data');
fd.append('AWSAccessKeyId', 'XXXX');
fd.append('policy', s3Url.s3Policy);
fd.append('signature', s3Url.s3Signature);
fd.append('file', file);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://XXXX.s3.amazonaws.com', true);
/////////////////////////////////////////////////////////
// Keep track of upload progress so that we can message//
// it to the user. //
/////////////////////////////////////////////////////////
var firstProgressEvent = true;
xhr.loaded = 0;
xhr.upload.addEventListener('progress', function(e) {
if (firstProgressEvent) {
firstProgressEvent = false;
}
xhr.loaded += (e.loaded - xhr.loaded);
$('progress').val((xhr.loaded / e.total) * 100);
}, false);
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 ) {
if ( xhr.status >= 200 && xhr.status < 400 ) {
cb(xhr.status);
} else {
cb(xhr.status);
}
}
};
xhr.onerror = function () {
error(xhr, xhr.status);
};
xhr.send(fd);
};
});
在服务器上:
createS3Policy = function(key, callback) {
var date = new Date();
var s3Policy = {
"expiration": new Date(Date.now() + 300000),
"conditions": [
{"bucket": "XXX"},
["starts-with", "$key", key],
{"acl": "public-read"},
["starts-with", "$Content-Type", "multipart/form-data"],
["content-length-range", 0, 524288000]
]
};
////////////////////////////////////
// stringify and encode the policy//
////////////////////////////////////
var stringPolicy = JSON.stringify(s3Policy);
var base64Policy = Buffer(stringPolicy, "utf8").toString("base64");
////////////////////////////////////
// sign the base64 encoded policy //
////////////////////////////////////
var signature = crypto.createHmac("sha1", process.env.AWS_SECRET_ACCESS_KEY)
.update(new Buffer(base64Policy, "utf8")).digest("base64");
////////////////////////////////////
// build the results object //
////////////////////////////////////
var s3Credentials = {
s3Policy: base64Policy,
s3Signature: signature
};
callback(s3Credentials);
};
相关文章:
- Jquery keep Alive/任何客户端交互
- 正在使用在服务器端或客户端执行的 Jquery 函数
- 使用send时,jquery文件上传不调整图像客户端的大小
- Telerik RadGrid排序客户端JavaScript jQuery
- 在JS或jQuery或任何客户端脚本的帮助下,通过查看源代码读取源代码
- RSS Feeds - 添加服务器端(PHP)或客户端(JavaScript / jQuery)
- jQuery$.get从物理客户端站点返回403
- 需要将数据从NodeJS服务器发送回JQuery客户端
- Jquery 客户端验证不起作用
- HTML/jQuery 客户端和 PHP 后端用于 Twitter oAuth
- jQuery 客户端分页在关联多维数组上
- JQuery客户端在localhost外部失败
- 用于REST web服务的JavaScript/jQuery客户端
- Jquery客户端验证与Jquery日期picker
- 在asp.net c#中使用javaScript/jquery客户端进行gridview计算
- 让 CORS 与 JQuery 客户端、节点/快速服务器一起工作时出现问题
- JQuery 客户端搜索
- jQuery +客户端模板=“语法错误,无法识别的表达式”
- rails日期时间选择的jQuery客户端验证
- 如何使用jquery客户端从另一个域POST到启用Web api的服务器