AWS 预签名的 PUT 请求上的 SignatureDoesNotMatch url
SignatureDoesNotMatch on PUT request for AWS presigned url
有很多questions/answer与此相关,但它们似乎不适用于我的情况,或者答案似乎没有解决这个问题。
我有一个 AWS lambda 函数,它 return 是一个由此函数生成的 getSignedUrl
: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`
})
})
})
}
我的意图是生成一个 URL(即 uploadURL
),我可以向其 post/put/send 一个 csv 文件,然后这个 csv 自动保存在 s3桶 uploadBucket
。我有一个 AWS API 网关指向具有特定 url 端点的此函数。我可以向此 API 端点发送 jquery GET 请求,它将 return uploadURL
.
var req = $.ajax({
method:"GET",
url:url_endpoint, // the API Gateway endpoint that points towards the lambda running `getUploadURL`
});
此处 req.response
文本似乎是正确的:
{"uploadURL":"https://materialcomv2.s3.eu-central-1.amazonaws.com/very_long_url","csvFileName":"1611509250475.csv"}
然后,我有一些 text/csv
数据,我打算将其发送到 uploadURL
data = "111,222,333\naaa,bbb,ccc\nAAA,BBB,CCC".
起初我尝试了一个简单的请求(如下),但是这个 return 一个 SignatureDoesNotMatch
错误。
req= $.ajax({
url: target_url, // this is the `uploadURL`
method:"put",
data:data, // this is the csv data
})
据我了解,这是由于 ajax put paramaters 与 lambda s3Params
不匹配造成的。我尝试添加 contentType:'text/csv',
和一个 key:csvFileName
。我尝试将其作为 blob
和表单数据发送,但都没有成功。
我需要更改什么才能不再获得 SignatureDoesNotMatch
并且可以成功将 csv 上传到存储桶?
首先,就我而言,我想发送一个 csv。我决定发送一个 .txt 文件,然后以 csv 格式读取它会更容易。这让我将内容类型更改为 'txt'.
除此之外,我需要将我的存储桶配置为(也)包含:
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"PUT"
]
接下来,在我的 ajax 放置请求中,它应该是:
$.ajax({
url: uploadURL,
type: "put", // I originally had method:"put", which was failing.
data: data, // Data here is just a string
contentType: 'text',
})
对我来说,在创建 S3 对象时设置签名版本解决了这个问题。
const s3 = new AWS.S3({
signatureVersion: "v4",
});
有很多questions/answer与此相关,但它们似乎不适用于我的情况,或者答案似乎没有解决这个问题。
我有一个 AWS lambda 函数,它 return 是一个由此函数生成的 getSignedUrl
: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`
})
})
})
}
我的意图是生成一个 URL(即 uploadURL
),我可以向其 post/put/send 一个 csv 文件,然后这个 csv 自动保存在 s3桶 uploadBucket
。我有一个 AWS API 网关指向具有特定 url 端点的此函数。我可以向此 API 端点发送 jquery GET 请求,它将 return uploadURL
.
var req = $.ajax({
method:"GET",
url:url_endpoint, // the API Gateway endpoint that points towards the lambda running `getUploadURL`
});
此处 req.response
文本似乎是正确的:
{"uploadURL":"https://materialcomv2.s3.eu-central-1.amazonaws.com/very_long_url","csvFileName":"1611509250475.csv"}
然后,我有一些 text/csv
数据,我打算将其发送到 uploadURL
data = "111,222,333\naaa,bbb,ccc\nAAA,BBB,CCC".
起初我尝试了一个简单的请求(如下),但是这个 return 一个 SignatureDoesNotMatch
错误。
req= $.ajax({
url: target_url, // this is the `uploadURL`
method:"put",
data:data, // this is the csv data
})
据我了解,这是由于 ajax put paramaters 与 lambda s3Params
不匹配造成的。我尝试添加 contentType:'text/csv',
和一个 key:csvFileName
。我尝试将其作为 blob
和表单数据发送,但都没有成功。
我需要更改什么才能不再获得 SignatureDoesNotMatch
并且可以成功将 csv 上传到存储桶?
首先,就我而言,我想发送一个 csv。我决定发送一个 .txt 文件,然后以 csv 格式读取它会更容易。这让我将内容类型更改为 'txt'.
除此之外,我需要将我的存储桶配置为(也)包含:
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"GET",
"PUT"
]
接下来,在我的 ajax 放置请求中,它应该是:
$.ajax({
url: uploadURL,
type: "put", // I originally had method:"put", which was failing.
data: data, // Data here is just a string
contentType: 'text',
})
对我来说,在创建 S3 对象时设置签名版本解决了这个问题。
const s3 = new AWS.S3({
signatureVersion: "v4",
});