AWS S3使用元数据预签名URL



我正在尝试使用下面的boto3创建预先签名的url

s3 = boto3.client(
's3', 
aws_access_key_id=settings.AWS_ACCESS_KEY, 
aws_secret_access_key=settings.AWS_ACCESS_SECRET, 
region_name=settings.AWS_SES_REGION_NAME,
config=Config(signature_version='s3v4')
)
metadata = {
'test':'testing'
}
presigned_url = s3.generate_presigned_url(
ClientMethod='put_object', 
Params={
'Bucket': settings.AWS_S3_BUCKET_NAME,
'Key': str(new_file.uuid),
'ContentDisposition': 'inline',
'Metadata': metadata
})

因此,在生成URL并尝试使用Ajax将其上传到S3之后,它给出了403禁止。如果我在创建URL时删除元数据和ContentDisposition,它就会成功上传。

Boto3版本:1.9.33

以下是我所指的医生:https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#S3.Client.generate_presigned_url

是的,我成功了,基本上,在生成签名的URL之后,我需要在标头中发送所有元数据和内容处置以及签名的URL。例如:我的元数据字典是{'test':'test'},然后我需要将此元数据在标头中发送,即x-amz-meta-test及其值和内容处理到AWS

我使用的是createPresignedPost,对我来说,我通过向Fields参数添加我想要的元数据来实现这一点,如下所示:-

const params = {
Expires: 60,
Bucket: process.env.fileStorageName,
Conditions: [['content-length-range', 1, 1000000000]], // 1GB
Fields: {
'Content-Type': 'application/pdf',
key: strippedName,
'x-amz-meta-pdf-type': pdfType,
'x-amz-meta-pdf-id': pdfId,
},
};

只要您将文件元数据中所需的数据传递给用于创建preSignedPost响应的lambda,那么以上操作就可以了。希望能帮助其他人。。。

我发现元数据对象需要是键/值对,值为字符串(例如Nodejs lambda(:

const AWS = require('aws-sdk');
const s3 = new AWS.S3();
exports.handler = async (event) => {
const { key, type, metadata } = JSON.parse(event.body);
// example
/*metadata: {
foo: 'bar',
x: '123',
y: '22.4213213'
}*/
return await s3.getSignedUrlPromise('putObject', {
Bucket: 'the-product-uploads',
Key: key,
Expires: 300,
ContentType: type,
Metadata: metadata
});
};

然后,在您的请求标头中,您需要明确地添加每个k/v:

await fetch(signedUrl, {
method: "PUT",
headers: {
"Content-Type": fileData.type,
"x-amz-meta-foo": "bar",
"x-amz-meta-x": x.toString(),
"x-amz-meta-y": y.toString()
},
body: fileBuffer
});

在boto中,您应该提供Metadata参数,该参数传递键、值元数据的dict。您不需要将密钥命名为x-amz-meta,因为显然boto现在正在为您命名。

此外,当上传到预先签名的URL:时,我不必再次传递元数据

params = {'Bucket': bucket_name, 
'Key': object_key, 
'Metadata': {'test-key': value}
}
response = s3_client.generate_presigned_url('put_object',
Params=params,
ExpiresIn=3600)

我在API 后面的lambda函数中使用了类似的代码

相关内容

  • 没有找到相关文章

最新更新