我正在构建一个包含文件上传功能的Web应用程序.我的目标是从用户直接上传到S3存储桶.策略是预先签署将作为表单提交的POST请求.
包版是一个SignatureDoesNotMatch
错误 - 据我所知,我已经符合文档,并且已经探索了很多选项,但仍然无法解决.我能够生成预先签名的下载链接.
引用:
AWS POST文档
例
boto3 generate_presigned_post
参考
生成签名请求:
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} ] )
上传表格(fields
上面填写):
{{ creds }}
响应的相关部分:
SignatureDoesNotMatch
The request signature we calculated does not match the signature you provided. Check your key and signing method. AKI--snip-- eyJjb25kaXRpb25zIjogW3siYWNsIjogInByaXZhdGUifSwgeyJ4LWFtei1hbGdvcml0aG0iOiAiQVdTNC1ITUFDLVNIQTI1NiJ9LCB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJQUlDVjRNVlBUUlFHU1lLV1EvMjAxNTEyMTgvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LCB7IngtYW16LWRhdGUiOiAiMjAxNTEyMThUMDAwMDAwWiJ9LCB7ImJ1Y2tldCI6ICJsZWFzeSJ9LCBbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAiIl1dLCAiZXhwaXJhdGlvbiI6ICIyMDE1LTEyLTE4VDA1OjEwOjU2WiJ9 wDOjsBRc0iIW7JNtz/4GHgfvKaU=
StringToSign
以上错误的Base64解码:
{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'}
A---.. 5
找到了解决方案:必须明确配置s3客户端以使用Amazon的新签名v4。发生错误是因为它默认为旧版本,从而导致不匹配。一点点脸药-当时不是用boto3文档编写的,尽管亚马逊的人说应该很快。
该方法得到了简化,因为它现在可以精确返回所需的字段:
def s3_upload_creds(name): BUCKET = 'mybucket' REGION = 'us-west-1' s3 = boto3.client('s3', region_name=REGION, config=Config(signature_version='s3v4')) key = '${filename}' return s3.generate_presigned_post( Bucket = BUCKET, Key = key )
这意味着可以轻松生成表格:
{{ creds }}
干杯
找到了解决方案:必须明确配置s3客户端以使用Amazon的新签名v4。发生错误是因为它默认为旧版本,从而导致不匹配。一点点脸药-当时不是用boto3文档编写的,尽管亚马逊的人说应该很快。
该方法得到了简化,因为它现在可以精确返回所需的字段:
def s3_upload_creds(name): BUCKET = 'mybucket' REGION = 'us-west-1' s3 = boto3.client('s3', region_name=REGION, config=Config(signature_version='s3v4')) key = '${filename}' return s3.generate_presigned_post( Bucket = BUCKET, Key = key )
这意味着可以轻松生成表格:
{{ creds }}
干杯