Node.js Lambda S3 getObject(从ajax调用激发)抛出403被拒绝

Node.js Lambda S3 getObject(从ajax调用激发)抛出403被拒绝,node.js,amazon-s3,aws-lambda,Node.js,Amazon S3,Aws Lambda,我有一个lambda函数,它从一个bucket中获取一个图像,调整其大小,然后将其放入另一个bucket中。lambda函数设置为在源bucket中创建文件时触发。相当标准,教程级的东西 当我使用AWSWebUI将图像放入源bucket中时,一切正常 但是,当我使用web应用程序中的xhr将图像放入同一个存储桶时,会出现以下错误(从s3.getObject调用中抛出): 经过广泛搜索,大多数人认为403个错误通常归结为lambda函数的角色/策略权限。但是当我浏览日志时,我看到的xhr上传和AW

我有一个lambda函数,它从一个bucket中获取一个图像,调整其大小,然后将其放入另一个bucket中。lambda函数设置为在源bucket中创建文件时触发。相当标准,教程级的东西

当我使用AWSWebUI将图像放入源bucket中时,一切正常

但是,当我使用web应用程序中的xhr将图像放入同一个存储桶时,会出现以下错误(从s3.getObject调用中抛出):

经过广泛搜索,大多数人认为403个错误通常归结为lambda函数的角色/策略权限。但是当我浏览日志时,我看到的xhr上传和AWSWebUI上传之间的唯一区别是eventName和userIdentity

对于web UI上载,它的Put和principalId:

eventName: 'ObjectCreated:Put',
userIdentity: { principalId: 'AWS:AIDAJ2VMZPNX5NJD2VBLM' }
但在xhr电话中,它是Post和匿名的:

eventName: 'ObjectCreated:Post',
userIdentity: { principalId: 'Anonymous' }
我的Lambda角色附带了两个策略:

AWSLambdaExecute

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:*"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::*"
        }
    ]
}
AWSLambdaBasic执行角色

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}
我的S3存储桶具有以下策略:

源存储桶:

{
    "Version": "2012-10-17",
    "Id": "Lambda access bucket policy",
    "Statement": [
        {
            "Sid": "All on objects in bucket lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::source-bucket-name/*"
        },
        {
            "Sid": "All on bucket by lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::source-bucket-name"
        }
    ]
}
function uploadFileAttachment(attachment, form) {

  var formButtons = document.querySelectorAll("form.form--trix button.btn");

  formButtons.forEach((button) => {
    button.setAttribute("disabled", "disabled");
  });

  uploadFile(attachment.file, setProgress, setAttributes)

  function setProgress(progress) {
    attachment.setUploadProgress(progress)
  }

  function setAttributes(attributes) {

    attachment.setAttributes(attributes)

    formButtons.forEach((button) => {
      button.removeAttribute("disabled");
    });

  }
}

function uploadFile(file, progressCallback, successCallback) {

  var key = createStorageKey(file)
  var formData = createFormData(key, file)
  var xhr = new XMLHttpRequest()

  xhr.open("POST", global.s3url, true)

  xhr.upload.addEventListener("progress", function(event) {
    var progress = event.loaded / event.total * 100
    progressCallback(progress)
  })

  xhr.addEventListener("load", function(event) {
    if (xhr.status == 204) {
      var attributes = {
        url: global.s3url + key,
        href: global.s3url + key + "?content-disposition=attachment"
      }
      successCallback(attributes)
    }
  })

  xhr.send(formData);
}

function createStorageKey(file) {
  var date = new Date()
  var day = date.toISOString().slice(0,10)
  var name = date.getTime() + "-" + file.name
  return [ "trix", day, name ].join("/")
}

function createFormData(key, file) {
  var data = new FormData()
  data.append("key", key)
  data.append("Content-Type", file.type)
  data.append("file", file)
  return data
}
目标存储桶:

{
    "Version": "2012-10-17",
    "Id": "Lambda access bucket policy",
    "Statement": [
        {
            "Sid": "All on objects in bucket lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::destination-bucket-name/*"
        },
        {
            "Sid": "All on bucket by lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::destination-bucket-name"
        }
    ]
}
我是否需要以某种方式将主体Id传递(或分配)给我的xhr调用以使其工作?或者我是否需要将权限/策略/角色添加到我的函数中,以允许它在没有将主体Id附加到触发器的情况下启动函数

编辑: 下面是将POST文件发送到源bucket的JS代码:

{
    "Version": "2012-10-17",
    "Id": "Lambda access bucket policy",
    "Statement": [
        {
            "Sid": "All on objects in bucket lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::source-bucket-name/*"
        },
        {
            "Sid": "All on bucket by lambda",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::source-bucket-name"
        }
    ]
}
function uploadFileAttachment(attachment, form) {

  var formButtons = document.querySelectorAll("form.form--trix button.btn");

  formButtons.forEach((button) => {
    button.setAttribute("disabled", "disabled");
  });

  uploadFile(attachment.file, setProgress, setAttributes)

  function setProgress(progress) {
    attachment.setUploadProgress(progress)
  }

  function setAttributes(attributes) {

    attachment.setAttributes(attributes)

    formButtons.forEach((button) => {
      button.removeAttribute("disabled");
    });

  }
}

function uploadFile(file, progressCallback, successCallback) {

  var key = createStorageKey(file)
  var formData = createFormData(key, file)
  var xhr = new XMLHttpRequest()

  xhr.open("POST", global.s3url, true)

  xhr.upload.addEventListener("progress", function(event) {
    var progress = event.loaded / event.total * 100
    progressCallback(progress)
  })

  xhr.addEventListener("load", function(event) {
    if (xhr.status == 204) {
      var attributes = {
        url: global.s3url + key,
        href: global.s3url + key + "?content-disposition=attachment"
      }
      successCallback(attributes)
    }
  })

  xhr.send(formData);
}

function createStorageKey(file) {
  var date = new Date()
  var day = date.toISOString().slice(0,10)
  var name = date.getTime() + "-" + file.name
  return [ "trix", day, name ].join("/")
}

function createFormData(key, file) {
  var data = new FormData()
  data.append("key", key)
  data.append("Content-Type", file.type)
  data.append("file", file)
  return data
}

你也可以分享ajax代码吗?@AmitBaranes我刚刚编辑了我的问题,添加了JS。