带有元数据的 AWS S3 预签名 URL

Dhr*_*min 6 django python-2.7 boto3

我正在尝试使用下面的 boto3 创建 presigned-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
})
Run Code Online (Sandbox Code Playgroud)

因此,在生成 URL 后,我尝试使用 Ajax 将其上传到 S3,它给出了 403 forbidden。如果我在创建 URL 时删除 Metadata 和 ContentDisposition,它将成功上传。

Boto3 版本:1.9.33

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

Dhr*_*min 6

是的,我开始工作了,基本上在生成签名 URL 之后,我需要将所有元数据和 Content-Dispostion 与签名 URL 一起发送到标头中。例如:我的元数据字典是 {'test':'test'} 然后我需要将此元数据发送到标头中,即x-amz-meta-test连同它的值和内容分配到 AWS

  • 这是否意味着,您需要在生成预签名 URL 时将其添加到“Params”中,并由使用此预签名 URL 上传文件的客户端将其发送到标头中? (3认同)

Mat*_*att 5

我发现元数据对象需要是键/值对,值作为字符串示例是 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
    });
};
Run Code Online (Sandbox Code Playgroud)

然后在请求标头中,您需要显式添加每个 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
    });
Run Code Online (Sandbox Code Playgroud)