Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
702 views
in Technique[技术] by (71.8m points)

jquery - SignatureDoesNotMatch on PUT request for AWS presigned url

There are a number of questions/answer related to this, but they do not seem to apply to my situation or the answer does not appear to solve this.

I have a AWS lambda function that returns a getSignedUrl generated by this function: getUploadURL

const getUploadURL = async function() {
  console.log('getUploadURL started')
  let actionId = Date.now()

  var s3Params = {
    Bucket: uploadBucket,
    Key:  `${actionId}.csv`,
    ContentType: 'text/csv',
  };

  return new Promise((resolve, reject) => {
    // Get signed URL
    let uploadURL = s3.getSignedUrl('putObject', s3Params)
    resolve({
      "statusCode": 200,
      "isBase64Encoded": false,
      "headers": {
        "Access-Control-Allow-Origin": "*"
      },
      "body": JSON.stringify({
          "uploadURL": uploadURL,
          "csvFileName": `${actionId}.csv`
      })
    })
  })
}

My intention is that this generates a URL (i.e., uploadURL), to which I can post/put/send a csv file, and that this csv is then automatically saved at s3 bucket uploadBucket. I have an AWS API gateway pointing towards this function with a specific url endpoint. I can send a jquery GET request to this API endpoint, and it will return the uploadURL.

var req = $.ajax({ 
      method:"GET",
      url:url_endpoint, // the API Gateway endpoint that points towards the lambda running `getUploadURL`
    });

Here req.response text appears to be correct:

{"uploadURL":"https://materialcomv2.s3.eu-central-1.amazonaws.com/very_long_url","csvFileName":"1611509250475.csv"}

Then, I have some text/csv data, which I intend to send to the uploadURL

data = "111,222,333
aaa,bbb,ccc
AAA,BBB,CCC". 

At first I tried a simple request (below), but this return an SignatureDoesNotMatch error.

req= $.ajax({
      url: target_url, // this is the `uploadURL`
      method:"put", 
      data:data, // this is the csv data
    })

Based on what I understand, this is caused by the ajax put paramaters not matching the lambda s3Params. I tried to add contentType:'text/csv', and a key:csvFileName. I tried to send it as a blob, and as a formdata, but all to no success.

What do I need to change so I no longer get the SignatureDoesNotMatch and can succesfully upload a csv to a bucket?

question from:https://stackoverflow.com/questions/65873996/signaturedoesnotmatch-on-put-request-for-aws-presigned-url

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

First of all, in my case I wanted to send a csv. I decided it'd be easier to send a .txt file, and then read it as csv. This made me change my content-type to 'txt'.

Besides this, I needed to have my bucket configured to (also) contain:

 "AllowedHeaders": [
      "*"
  ],
  "AllowedMethods": [
      "GET",
      "PUT"
  ]

Next, in my ajax put request, it should read:

$.ajax({
      url: uploadURL, 
      type: "put",  // I originally had method:"put", which was failing. 
      data: data,   // Data here is just a string
      contentType: 'text',
    })

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...