python - 直接从Heroku上的Django发送文件到S3

时间:2017-04-29 05:59:56

标签: python django heroku amazon-s3

因此我尝试将较大的文件上传到我的网站,由于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);
}

0 个答案:

没有答案