我尝试使用Heroku
从S3
上传到boto3
,但我一直收到错误<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
。我已尝试使用pre-signed post
和pre-signed url
,但错误仍然存在。我提供给Heroku以提出请求的凭据是我的根AWSAccessKeyID和密钥,因此我不应该遇到权限问题。我可以从命令行直接上传到S3。
生成预先签名的帖子后返回的值:
{'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'}
目前在Heroku上的代码:
@api.route('/post_track', methods=['POST'])
@login_required
def post_track():
if request.method == 'POST':
file = request.files['file']
track = Track.upload_fromJSON(request.form.get('share'), request.form.get('title'))
//Postgres entry
conn = get_conn()
with conn.cursor() as cur:
cur.execute('INSERT INTO tracks(user_id, title, share)'
'VALUES (%s, %s, %s) RETURNING id;',
(track.user_id, track.title, track.share))
track_id = cur.fetchone()[0]
conn.commit()
//Obtain pre-signed request
signed_request = get_signed_request(track.title, request.form.get('type'), track_id, file)
return json.dumps({'response':signed_request})
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"], data=presigned_post["fields"], files=files)
print(r_response)
print(r_response.text)
我最终将设置代码以将预先签名的请求返回到我的前端并从那里直接上传。只是做这个测试运行。
答案 0 :(得分:1)
我真的很难用这个。我联系了S3支持,他们说他们收到的请求看起来很好,并且使用Heroku生成签名的方式肯定有问题。我联系了Heroku,他们并没有真正回应。解决问题的是删除我的AWS root访问权限并生成新的访问权限,然后使用新的访问ID重新配置heroku。超级简单,但非常奇怪,这就是问题。希望这可以帮助处理相同问题的人。