使用S3 putObject preigned url的签名无效

时间:2016-01-22 01:02:08

标签: amazon-s3 lambda pre-signed-url

我正在使用lambda函数创建一个预先指定的URL来上传到S3:

var crypto = require('crypto');
var AWS = require('aws-sdk');

AWS.config.region = 'eu-west-1';

function randomValueHex (len) {
    return crypto.randomBytes(Math.ceil(len/2))
        .toString('hex') // convert to hexadecimal format
        .slice(0,len);   // return required number of characters
}

var value1 = randomValueHex(12)

exports.handler = function(event, context) {
    var key = randomValueHex(16);
    // Url is
    var s3 = new AWS.S3();
    var params = {Bucket: 'somebucket', Key: key };
    var url = s3.getSignedUrl('putObject', params);
    context.succeed({ key: key, url: url });
}

然后使用该URL我尝试使用httpie进行PUT调用:

echo "something" | http -v PUT https://...presigned url

然而我得到了:

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

lambda以完整的s3访问执行角色运行,但权限不应该是这里的问题

更新:尝试上传没有内容类型标题的文件可以正常工作:

http -v PUT https://...url

所以似乎问题在于内容类型,但由于我没有指定它,我认为AWS不会打扰如果我上传json或其他任何东西

1 个答案:

答案 0 :(得分:0)

至少在签名版本2中,Content-Type标题中的值是签名算法的一个组成部分......所以如果getSignedUrl不知道你要放什么在那里,它将生成一个无效的签名。

您应该可以将其添加到params中的键/值对:

ContentType, 'text/plain' // using the appropriate mine type string