发出 Post 请求时,S3 元素值的必需顺序是什么?

what is the required order for S3 element values when making a Post request?

我正在尝试通过以下方式将文件上传到 S3:

r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)

但我收到以下错误:

Bucket POST must contain a field named 'key'. If it is specified, please check the order of the fields.

但我肯定会包含一个 key 值。我看到的另一个答案建议使用我正在尝试做的 OrderedDict ,但是查看下面的 S3 文档,我看不到它在哪里为它们的键指定所需的顺序,发出请求时值数据.

http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTForms.html http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html

有人有什么建议吗?

Boto3 returns 具有以下顺序的元素值的字典:x-amz-signaturex-amz-algorithmkeyx-amz-credentialpolicy, 和 x-amz-date 我只是在使用同一个字典。

def get_signed_request(title, type, track_id, file):
    S3_BUCKET = os.environ.get('S3_BUCKET')
    file_name = title
    file_type = type
    region = 'us-east-1'
    s3 = boto3.client('s3', region_name=region, config=Config(signature_version='s3v4'))

    presigned_post = s3.generate_presigned_post(
        Bucket = S3_BUCKET,
        Key = file_name
    )

    files = {'file': file}

    r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)

打印presigned_post的内容,显示密钥:

 {'fields': {'x-amz-signature': '26eff5417d0d11a25dd294b059a088e2be37a97f14713962f4240c9f4e33febb', 'x-amz-algorithm': 'AWS4-HMAC-SHA256', 'key': u'sound.m4a', 'x-amz-credential': u'<AWSAccessID>/20161011/us-east-1/s3/aws4_request', 'policy': u'eyJjb25kaXRpb25zIjogW3siYnVja2V0IjogImZ1dHVyZWZpbGVzIn0sIHsia2V5IjogInNvdW5kLm00YSJ9LCB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sIHsieC1hbXotY3JlZGVudGlhbCI6ICJBS0lBSTdLRktCTkJTNEM0VktKQS8yMDE2MTAxMS91cy1lYXN0LTEvczMvYXdzNF9yZXF1ZXN0In0sIHsieC1hbXotZGF0ZSI6ICIyMDE2MTAxMVQyMDM4NDlaIn1dLCAiZXhwaXJhdGlvbiI6ICIyMDE2LTEwLTExVDIxOjM4OjQ5WiJ9', 'x-amz-date': '20161011T203849Z'}, 'url': u'https://s3.amazonaws.com/bucketname'}

我原来在做:

r_response = requests.post(presigned_post["url"], json=presigned_post["fields"], files=files)

我将 json 更改为 data 并且有效:

r_response = requests.post(presigned_post["url"], data=presigned_post["fields"], files=files)

不幸的是,我遇到了另一个错误:

<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>