Im trying to sign a url using boto3 like this:
@list_route(methods=['get'])
def sign(self, request):
key = request.GET.get('key', None)
if key:
if key.count('.') == 1 and key.count('/') == 1:
extension = key.split('.')
if '*' in settings.ALLOWED_FILE_TYPES or extension.lower() in settings.ALLOWED_FILE_TYPES:
# Get the service client
s3 = boto3.client('s3')
# Generate the POST attributes
post = s3.generate_presigned_url(
'put_object',
{'Bucket': settings.FILE_BUCKET, 'Key': 'tmp/{}'.format(key)},
300,
'PUT'
)
return Response(
status=200,
data={'presigned_post': post}
)
else:
return Response(
status=400,
data="File Type not Allowed"
)
else:
return Response(
status=400,
data="Invalid Key"
)
else:
return Response(
status=400,
data='Missing Key'
)
I can generate the URL and then make the following request to upload the file on a Saga on react:
// Generate Signed URL
const resultSignUrl = yield call([File.custom, 'sign'], {token, params:{key: data.key}});
let signedUrl = resultSignUrl.presigned_post;
let options = {
headers: {
'Content-Type': file.type
}
};
console.log("SIGN URL", resultSignUrl);
console.log("SIGN URL file", file);
// Upload to S3
const resultUpload = yield call([axios, 'put'], signedUrl, file, options);
console.log("S3 UPLOAD", resultUpload);
The problem is that AWS replies this when I make the request:
<?xml version="1.0" encoding="UTF-8"?>
<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>"SomeAccessKey"</AWSAccessKeyId><StringToSign>PUT
application/vnd.oasis.opendocument.text
1516318279
/student-tracker-files/tmp/14a09716-8850-47cb-bf3a-7820f42c97d4/test%20honduras.odt</StringToSign><SignatureProvided>EFqdML8OgILC/L/hoJBqmyhuzRk=</SignatureProvided><StringToSignBytes>50 55 54 0a 0a 61 70 70 6c 69 63 61 74 69 6f 6e 2f 76 6e 64 2e 6f 61 73 69 73 2e 6f 70 65 6e 64 6f 63 75 6d 65 6e 74 2e 74 65 78 74 0a 31 35 31 36 33 31 38 32 37 39 0a 2f 73 74 75 64 65 6e 74 2d 74 72 61 63 6b 65 72 2d 66 69 6c 65 73 2f 74 6d 70 2f 31 34 61 30 39 37 31 36 2d 38 38 35 30 2d 34 37 63 62 2d 62 66 33 61 2d 37 38 32 30 66 34 32 63 39 37 64 34 2f 74 65 73 74 25 32 30 68 6f 6e 64 75 72 61 73 2e 6f 64 74</StringToSignBytes><RequestId>193F6C165445A3E4</RequestId><HostId>odoIo4+4sdVUuDJucnrkzeyJJUYJ5sMDqpS7DAzV3nJvSrN4Eu+7b1Srs2FEQy2aDHuYEakMBGY=</HostId></Error>
Can anyone tell me what I might be doing wrong? I have changed the acces key and secret and still get the same response. I have read the docs on boto3 but I see no difference between my code and the one they show in their examples.
You should try to add content type to the django boto function
ost = s3.generate_presigned_url(
'put_object',
{'Bucket': settings.FILE_BUCKET,
'ContentType': request.GET.get('type'),
'Key': 'tmp/{}'.format(key)},
3600,
'PUT'
)