Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Amazon s3 AWS Lambda S3获取/发布签名不匹配错误_Amazon S3_Aws Lambda - Fatal编程技术网

Amazon s3 AWS Lambda S3获取/发布签名不匹配错误

Amazon s3 AWS Lambda S3获取/发布签名不匹配错误,amazon-s3,aws-lambda,Amazon S3,Aws Lambda,我已经有一个Lambda node.js函数启动并运行了大约6个月,没有任何问题。该函数只需获取一个对象并将其从一个bucket复制到另一个bucket 今天,我开始了解: “SignatureDesNotMatch:我们计算的请求签名不匹配 匹配您提供的签名。请检查您的密钥和签名方法。“ 我使用的代码非常简单,有没有关于如何解决这个问题的建议 var aws = require('aws-sdk'); var s3 = new aws.S3({apiVersion: '2006-03-01'}

我已经有一个Lambda node.js函数启动并运行了大约6个月,没有任何问题。该函数只需获取一个对象并将其从一个bucket复制到另一个bucket

今天,我开始了解:

“SignatureDesNotMatch:我们计算的请求签名不匹配 匹配您提供的签名。请检查您的密钥和签名方法。“

我使用的代码非常简单,有没有关于如何解决这个问题的建议

var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});

exports.handler = function(event, context) {

  var to_bucket = 'my_to_bucket/test';
  var from_bucket = event.Records[0].s3.bucket.name;
  var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
  var size = Math.floor(event.Records[0].s3.object.size / 1024);

  s3.getObject({Bucket: from_bucket, Key: key}, function(err, data) {
    if (err) {
      // send a webhook
    } 
    else {
      s3.putObject({Bucket: to_bucket, Key: key, Body: data.Body, ContentType: data.ContentType}, 
      function(err, data) {
        if (err) {
          // send a webhook
        }
        else {
          // send a webhook
        }
      });
    } // end else
  }); // end getobject
};
更新:
我发现,如果发送到桶中,效果很好。如果我发送到同一个bucket的任何子文件夹,它都会失败。我确实发送到一个子文件夹,并在开始时简化了上面的代码,但我已将其更新为在to_bucket中显示一个子文件夹。

我找到了一个解决方案。在意识到这是由于bucket中的文件夹,而不仅仅是发送到bucket根目录后,我搜索并找到了以下帖子:

看起来bucket不应该包含子文件夹,而应该包含键。为什么到目前为止这一切都是个谜。以下是上述产品的更换代码:

var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});

exports.handler = function(event, context) {

  var to_bucket = 'my_to_bucket';
  var from_bucket = event.Records[0].s3.bucket.name;
  var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
  var size = Math.floor(event.Records[0].s3.object.size / 1024);

  s3.getObject({Bucket: from_bucket, Key: key}, function(err, data) {
    if (err) {
      // send a webhook
    } 
    else {
      key = 'subfolder/' + key;
      s3.putObject({Bucket: to_bucket, Key: key, Body: data.Body, ContentType: data.ContentType}, 
      function(err, data) {
        if (err) {
          // send a webhook
        }
        else {
          // send a webhook
        }
      });
    } // end else
  }); // end getobject
};

var key=decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g,”)看起来可疑。我认为键操作可能是个问题。@kixorz我刚刚改变了它,但它仍然失败,出现了同样的错误(并且已经正常运行了6个月)。谢谢您的尝试。另外,您正在第2行访问特定的API版本。我假设每个AWS API计算签名的方式不同。尝试使用最新的删除。另外,如果您将
aws sdk
与代码打包在一起,请尝试更新它。此错误消息来自其S3 API,因此问题在于客户端计算签名。@kixorz
decodeURIComponent(event.Records[0].S3.object.key.replace(/\+/g,”)是必需的,因为S3提供的键URL转义为+而不是
%20
。aws sdk将尝试为后续请求重新转义它,这肯定会让它变得毫无意义。我的S3 Lambda函数有非常相似的代码,所以我怀疑问题出在其他地方。从技术上讲,它不是一个子文件夹,而是一个键。它只显示为一个文件夹。他们可能在URL中添加/删除了额外的内容,这会导致签名不匹配。@Paul我的朋友,你帮我节省了几个小时!这件事今天才开始发生。谢谢大家分享所有的修正!保罗也一样!奇怪的是,使用bucket名称中指定的“folder”写入bucket可以工作,但从中读取会抛出此错误。谢谢你节省时间。