Heroku Node.js Amazon S3直接上传教程 - SignatureDoesNotMatch

时间:2014-05-25 17:31:48

标签: javascript node.js heroku amazon-s3 signature

为什么Heroku Nodejs AWS S3教程(https://devcenter.heroku.com/articles/s3-upload-node)在签名中出现加号'+'时失败?

2 个答案:

答案 0 :(得分:1)

摘要:重新生成签名,直到它不再包含加号'+'字符

if (signature.indexOf('+') != -1) {
    setTimeout(function(){
        //regenerate signature until it doesn't contain + anymore
        generateSignature();
    }, 400);
}

我发现的工作解决方案是由@chadsaun在此论坛帖子中提出的: http://www.uploadify.com/forum/#/discussion/comment/10777

完整的heroku示例代码解决方案:

app.get('/sign_s3', function(req, res){
    var object_name = req.query.s3_object_name;
    var mime_type = req.query.s3_object_type;
    var amz_headers = "x-amz-acl:public-read";
    var signature, expires;
    function generateSignature() {
        var thisTime = new Date().getTime();
        expires = Math.ceil((thisTime + 10000)/1000);
        var put_request = "PUT\n\n" + mime_type + "\n" 
                        + expires + "\n" + amz_headers 
                        + "\n/" + S3_BUCKET + "/"
                        + object_name;

        signature = crypto.createHmac('sha1', AWS_SECRET_KEY)
                        .update(put_request)
                        .digest('base64');
        console.log(signature);

        if (signature.indexOf('+') != -1) {
            setTimeout(function(){
                //regenerate signature until it doesn't contain + anymore
                generateSignature();
            }, 400);
        } else {
            var url = 'https://' + S3_BUCKET + '.s3.amazonaws.com/' + object_name;
            var credentials = {
                signed_request: url + "?AWSAccessKeyId=" + AWS_ACCESS_KEY 
                                + "&Expires=" + expires + "&Signature=" 
                                + signature,
                url: url,
            };

            res.write(JSON.stringify(credentials));
            res.end();
        }
    }
    generateSignature();
});

答案 1 :(得分:0)

我猜你需要对你的签名进行编码。像这样:

signature = encodeURIComponent(
    crypto.createHmac('sha1', AWS_SECRET_KEY)
        .update(put_request)
        .digest('base64')
);

这样您就不需要检查签名是否包含' +'