嗨:)当我尝试直接将文件上传到AWS S3时,我收到此错误:
The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.
似乎我在签署v4 hmac授权签名时遗漏了一些内容:\
html文件:
<form action="https://mybucket.s3.eu-central-1.amazonaws.com/" enctype="multipart/form-data" id="form-upload" method="POST">
<input type="hidden" name="AWSAccessKeyId" value="myPublicKey">
<input type="hidden" name="acl" value="private">
<input type="hidden" name="success_action_redirect" value="http://localhost:8080/uploadAfter">
<input type="hidden" name="Content-type" value=""> <!-- any file format -->
<input type="hidden" name="x-amz-algorithm" value="AWS4-HMAC-SHA256">
<!-- The following are injected by Javascript -->
<input type="hidden" name="key">
<input type="hidden" name="policy">
<input type="hidden" name="signature">
<input type="hidden" name="x-amz-credential">
<input type="hidden" name="x-amz-date">
<input type="hidden" name="x-amz-signature">
<input type="file" id="inputFile">
<button id="form-upload-submit" type="submit">Upload</button>
</form>
服务器端节点文件(“getS3Credentials ajax request”):
var crypto = require("crypto"),
AWS_ACCESS_KEY = process.env.AWS_ACCESS_KEY,
AWS_SECRET_KEY = process.env.AWS_SECRET_KEY,
dateNow = new Date().toISOString(),
dateNowRaw = dateNow.substr(0, dateNow.indexOf("T")).replace(/-/g, ""),
expiration = new Date();
expiration.setHours(expiration.getHours() + 1);
expiration = expiration.toISOString();
var policy = {
expiration: expiration,
conditions: [
{bucket: "mybucket"},
["starts-with", "$key", "files/filename"],
{acl: "private"},
{success_action_redirect: "http://localhost:8080/uploadAfter"},
["starts-with", "$Content-Type", ""],
["content-length-range", 0, 1024*1024*100],
{"x-amz-algorithm": "AWS4-HMAC-SHA256"},
{"x-amz-credential": AWS_ACCESS_KEY + "/" + dateNowRaw + "/eu-central-1/s3/aws4_request"},
{"x-amz-date": dateNow}
],
},
policyString = JSON.stringify(policy),
encodedPolicyString = new Buffer(policyString, "utf-8").toString("base64"),
dateKey = app.crypto
.createHmac("sha256", "AWS4" + AWS_SECRET_KEY)
.update(dateNowRaw)
.digest('binary'),
dateRegionKey = app.crypto
.createHmac("sha256", dateKey)
.update("eu-central-1")
.digest('binary'),
dateRegionServiceKey = app.crypto
.createHmac("sha256", dateRegionKey)
.update("s3")
.digest('binary'),
signinKey = app.crypto
.createHmac("sha256", dateRegionServiceKey)
.update("aws4_request")
.digest('binary'),
signature = app.crypto
.createHmac("sha256", signinKey)
.update(encodedPolicyString)
.digest('base64');
$.send({awskeyid: AWS_ACCESS_KEY, s3_policy: encodedPolicyString, s3_signature: signature, s3_key: "files/filename", s3_date_now: dateNow, s3_date_now_raw: dateNowRaw});
客户端js文件:
document.getElementById("form-upload-submit").onclick = function(evt) {
evt.preventDefault();
formUpload();
};
function formUpload() {
var xhr = new XMLHttpRequest();
xhr.open("POST", "/upload");
xhr.responseType = "json";
xhr.onload = processUpload;
xhr.send();
}
function processUpload() {
var response = this.response;
document.querySelector("#form-upload input[type='hidden'][name='key']").value = response.s3_key;
document.querySelector("#form-upload input[type='hidden'][name='policy']").value = response.s3_policy;
document.querySelector("#form-upload input[type='hidden'][name='signature']").value = response.s3_signature;
document.querySelector("#form-upload input[type='hidden'][name='x-amz-credential']").value = response.awskeyid + "/" + response.s3_date_now_raw + "/eu-central-1/s3/aws4_request";
document.querySelector("#form-upload input[type='hidden'][name='x-amz-date']").value = response.s3_date_now;
document.getElementById("form-upload").submit();
//The error is shown here as xml page, after the submitting of the form with the redirect to the amazon upload url
}
感谢您的帮助;)
答案 0 :(得分:0)
您应该删除字段&#39; AWSAccessKeyId&#39;从形式。
看来,如果您将此字段添加到表单,AWS会尝试使用SHA1验证签名,并忽略您提到的算法类型。
查看此aws post example,并检查表单中的字段是否与aws表单匹配(您可以使用此tool
另一种选择是使用SHA1散列