Tôi đang xây dựng một ứng dụng web bao gồm tính năng tải tệp lên. Mục tiêu của tôi là bắt đầu tải trực tiếp từ người dùng lên một thùng S3. Chiến lược này là ký trước một yêu cầu POST sẽ được gửi dưới dạng biểu mẫu.Tải lên dựa trên trình duyệt AWS S3 của Amazon bằng cách sử dụng POST -
Rào cản là lỗi SignatureDoesNotMatch
- theo như tôi có thể nói tôi đã tuân thủ tài liệu và đã khám phá nhiều tùy chọn nhưng vẫn không thể giải quyết được. Tôi có thể tạo các liên kết tải xuống được chỉ định.
Cách tham khảo:
boto3 generate_presigned_post
reference
Tạo yêu cầu ký:
def s3_upload_creds(name, user):
s3 = boto3.client('s3')
key = '${filename}'
region = 'us-east-1'
date_short = datetime.datetime.utcnow().strftime('%Y%m%d')
date_long = datetime.datetime.utcnow().strftime('%Y%m%dT000000Z')
fields = {
'acl': 'private',
'date': date_short,
'region': region,
'x-amz-algorithm': 'AWS4-HMAC-SHA256',
'x-amz-date': date_long
}
return s3.generate_presigned_post(
Bucket = 'leasy',
Fields = fields,
Key = key,
Conditions = [
{'acl': 'private'},
{'x-amz-algorithm': 'AWS4-HMAC-SHA256'},
{'x-amz-credential': '/'.join(['AKI--snip--', date_short, region, 's3', 'aws4_request'])},
{'x-amz-date': date_long}
]
)
hình thức tải lên (dân cư với fields
ở trên):
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
{{ creds }}
<form action="{{ creds.url }}" method="post" enctype="multipart/form-data">
Key to upload:
<input type="input" name="key" value="${filename}" /><br />
<input type="input" name="acl" value="{{ creds.fields.acl }}" />
<input type="hidden" name="Policy" value="{{ creds.fields.policy }}" />
<input type="text" name="X-Amz-Algorithm" value="{{ creds.fields['x-amz-algorithm'] }}" />
<input type="input" name="X-Amz-Credential" value="{{ creds.fields.AWSAccessKeyId }}/{{ creds.fields.date }}/us-east-1/s3/aws4_request" />
<input type="input" name="X-Amz-Date" value="{{ creds.fields['x-amz-date'] }}" />
<input type="input" name="X-Amz-Signature" value="{{ creds.fields.signature }}" />
File:
<input type="file" name="file" /> <br />
<!-- The elements after this will be ignored -->
<input type="submit" name="submit" value="Upload to Amazon S3" />
</form>
</html>
phần có liên quan của phản ứng:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
<AWSAccessKeyId>AKI--snip--</AWSAccessKeyId>
<StringToSign>
eyJjb25kaXRpb25zIjogW3siYWNsIjogInByaXZhdGUifSwgeyJ4LWFtei1hbGdvcml0aG0iOiAiQVdTNC1ITUFDLVNIQTI1NiJ9LCB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlDVjRNVlBUUlFHU1lLV1EvMjAxNTEyMTgvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LCB7IngtYW16LWRhdGUiOiAiMjAxNTEyMThUMDAwMDAwWiJ9LCB7ImJ1Y2tldCI6ICJsZWFzeSJ9LCBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAiIl1dLCAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTE4VDA1OjEwOjU2WiJ9
</StringToSign>
<SignatureProvided>wDOjsBRc0iIW7JNtz/4GHgfvKaU=</SignatureProvided>
Base64 decode của StringToSign
do lỗi trên:
{u'conditions': [{u'acl': u'private'},
{u'x-amz-algorithm': u'AWS4-HMAC-SHA256'},
{u'x-amz-credential': u'AKI--snip--/20151218/us-east-1/s3/aws4_request'},
{u'x-amz-date': u'20151218T000000Z'},
{u'bucket': u'leasy'},
[u'starts-with', u'$key', u'']],
u'expiration': u'2015-12-18T04:59:32Z'}
vĩ đại giải pháp! Đã thử thực hiện nó theo cách của bạn nhưng tôi vẫn nhận được cùng một lỗi từ S3. Tôi nhận thấy rằng các trường được trả về không bao gồm "Loại nội dung". Bạn có thể làm cho nó hoạt động mà không bao gồm loại nội dung không? – Brosef
@Brosef Đừng nhớ trường nào được trả về bởi generate_presigned_post. Tôi tin rằng thư viện được thiết kế để trả lại tất cả các lĩnh vực cần thiết. Bạn đã kiểm tra các tài liệu boto mới nhất chưa? Họ có thể đã thay đổi kể từ khi tôi trả lời. –