【问题标题】:Heroku Node.js Amazon S3 direct upload tutorial - SignatureDoesNotMatchHeroku Node.js Amazon S3 直接上传教程 - SignatureDoesNotMatch
【发布时间】:2014-07-14 12:24:01
【问题描述】:

当签名中出现加号“+”字符时,为什么 Heroku Nodejs AWS S3 教程 (https://devcenter.heroku.com/articles/s3-upload-node) 会失败?

【问题讨论】:

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


    【解决方案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();
    });
    

    【讨论】:

    • setTimeout() 用于防止可能的 generateSignature() loop from spamming Node.js 调用堆栈.
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2019-05-15
      • 2011-05-12
      • 2011-09-01
      • 2012-05-04
      • 2015-05-27
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      相关资源
      最近更新 更多