因此我尝试将较大的文件上传到我的网站,由于Herokus对尺寸的限制,我试图将它们直接上传到S3。 Heroku提供了有关如何执行此操作的精彩文档,seen here。我跟随指南,并根据this Git调整views.py
。问题是我的签名请求在尝试发布到S3时不起作用。我收到了错误
The request signature we calculated does not match the signature you provided. Check your key and signing method.
所以我不确定我的签名是如何错误的,或者我的javascript中是否有错误。任何帮助将不胜感激。
我的views.py
def sign_s3(request):
"""
https://devcenter.heroku.com/articles/s3-upload-python
"""
if request.user.is_authenticated():
user = request.user.id
AWS_ACCESS_KEY = AWS_ACCESS_KEY_ID
AWS_SECRET_KEY = AWS_SECRET_ACCESS_KEY
S3_BUCKET = AWS_STORAGE_BUCKET_NAME
object_name = urllib.parse.quote_plus(request.GET['file_name'])
mime_type = request.GET['file_type']
secondsPerDay = 24*60*60
expires = int(time.time()+secondsPerDay)
amz_headers = "x-amz-acl:public-read"
string_to_sign = "PUT\n\n%s\n%d\n%s\n/%s/%s" % (mime_type, expires, amz_headers, S3_BUCKET, object_name)
encodedSecretKey = AWS_SECRET_KEY.encode()
encodedString = string_to_sign.encode()
h = hmac.new(encodedSecretKey, encodedString, sha1)
hDigest = h.digest()
signature = base64.encodebytes(hDigest).strip()
print(signature)
signature = urllib.parse.quote_plus(signature)
print(signature)
url = 'https://%s.s3.amazonaws.com/media/user_%s/%s/' % (S3_BUCKET, user, object_name)
return JsonResponse({
'data': '%s?AWSAccessKeyId=%s&Expires=%s&Signature=%s' % (url, AWS_ACCESS_KEY, expires, signature),
'url': url,
})
我的javascript:
function getSignedRequest(file){
var token = $('input[name=csrfmiddlewaretoken]').val();
var xhr = new XMLHttpRequest();
xhr.open("GET", "/dashboard/sign_s3/?file_name="+file.name+"&file_type="+file.type);
// xhr.setRequestHeader('X-CSRF-Token', token);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
var response = JSON.parse(xhr.responseText);
uploadFile(file, response.data, response.url);
}
else{
alert("Could not get signed URL.");
}
}
};
xhr.send();
}
function uploadFile(file, s3Data, url){
var awskey = getParameterByName('AWSAccessKeyId', s3Data);
var expires = getParameterByName('Expires', s3Data);
var signature = getParameterByName('Signature', s3Data);
var xhr = new XMLHttpRequest();
var token = $('input[name=csrfmiddlewaretoken]').val();
xhr.open("POST", s3Data);
xhr.setRequestHeader('X-CSRF-Token', token);
var postData = new FormData();
postData.append('AWSAccessKeyId', awskey);
postData.append('Expires', expires);
postData.append('Signature', signature);
postData.append('file', file);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status === 204){
//do something
}
else{
alert("Could not upload file.");
}
}
};
xhr.send(postData);
}