2013-08-13 2 views
3

CORS를 Amazon S3 버킷에 업로드 할 수 있도록 Django 앱을 설정하려고합니다. 행운을 빕니다. 로컬 호스트와 웹 서버 모두에서 Firefox 및 Chrome 모두에서 403 Forbidden 메시지를 계속 수신합니다. 본인의 서명이 올바르게 계산되고 (아래에서 설명 함) 본인의 버켓 정책이 원점 * 허용, PUT/POST/GET 메소드 허용 및 헤더 허용 *임을 확인했습니다. 내 액세스 키/비밀 키 쌍이 정확하며 Cyberduck와 같은 소프트웨어를 통해 버켓에 액세스 할 수 있습니다. 그 밖의 무엇을 확인할 수 있습니까? 아니면 이것을 어떻게 디버깅 할 수 있습니까? 가능한 모든 길을 탐험 한 것 같은 느낌. 과 일치하도록 인코딩을 수정하면이 demo을 따르려고합니다.Amazon S3에 CORS 파일 업로드; s3upload.js example

이렇게하면 내 서명이 this Amazon S3 test file과 일치합니다. 내 서명 생성 코드는 여기에 있습니다 :

s3_bucket_name = settings.S3_BUCKET_NAME 
s3_access_key = settings.S3_ACCESS_KEY 
s3_secret_key = settings.S3_SECRET_KEY 

object_name = request.GET.get('s3_object_name') 
mime_type = request.GET.get('s3_object_type') 

expires = int(time.time()+300) 
amz_headers = "x-amz-acl:public-read" 

put_request = "PUT\n\n%s\n%d\n%s\n/%s/%s" % (mime_type, expires, amz_headers, s3_bucket_name, object_name) 

hashed = hmac.new(s3_secret_key, put_request, sha1) 
signature = binascii.b2a_base64(hashed.digest())[:-1] 
signature = urllib.quote_plus(signature.strip()) 

url = 'https://%s.s3.amazonaws.com/%s' % (s3_bucket_name, object_name) 

signed_request = '%s?AWSAccessKeyId=%s&Expires=%d&Signature=%s' % (url, s3_access_key, expires, signature) 

pdb.set_trace() 

return HttpResponse(json.dumps({ 
    'signed_request': signed_request, 
    'url': url 
    }), mimetype='application/json') 

내 업로드 기능 :

function s3_upload(filename) { 
filename = filename.split('\\').pop(); 
var s3upload = new S3Upload({ 
    file_dom_selector: '#video_file', 
    s3_sign_put_url: 'signS3put/', 
    s3_object_name: filename, 
    onProgress: function(percent, message, publicUrl, file) { 
     console.log('Upload progress: ', percent, message); 
    }, 
    onFinishS3Put: function(public_url, file) { 
     console.log('Upload finished: ', public_url); 
    }, 
    onError: function(status, file) { 
     console.log('Upload error: ', status); 
    } 
}); 
} 

그리고 내 파일 입력 버튼 :

video_form.append('<input class="input-block-level"' + 
      'autocomplete=off id="video_file" name="video_file"' + 
      'type=file required="required" onchange="' + 
        'var filename = $(this).val();' + 
        's3_upload(filename);" />'); 

이 지역 dev에 서버와 나를 모두 발생 원격 서버이므로이 SO post은 Chrome이 로컬 서버 CORS 호출을 차단하는 것에 대해 언급하지 않습니다.

팁 주셔서 감사합니다.

답변

5

그래서이 문제를 해결하고 다른 사람들에게 도움이 될 것입니다. (아무도이 문제를 가지고있는 것 같지 않습니다. 설치 프로그램이 다를 수도 있습니다.) 내 문제는 s3upload.js 라이브러리로 판명되었습니다. 두 가지 :

  1. 예를 들어 sign_s3보기가 public-read로 설정된 authenticated-read를 원했습니다. 보기에서 그것을 변경하는 것만으로도 도움이되지 않습니다 - x-amz-acl : public-read는 s3upload.js의 uploadToS3 함수 (줄 107)에 하드 코드되어 있습니다. 그래서 당신이 당신의보기에 맞게 변경해야합니다, 그렇지 않으면 나는 서명 인코딩이 CORS 요청 헤더와 일치하지 않는다고 생각합니다.
  2. =, + 및 /는 특수 문자로 나를 죽였습니다. 이것들은이 Amazon S3 article의 밑 부분에서 조심해야 할 것들로 언급되었으므로 해싱 알고리즘이 그것들을 대체했는지 확인했습니다. 문제는 내보기의 해싱 알고리즘이 세 문자를 이스케이프 문자로 올바르게 대체했지만 s3upload가이를 디코딩하고 =, + 및 /로 재 코딩했기 때문입니다. 나는 executeOnSignedUrl에 (라인 71) 한 줄을 변경 :

    return callback(result.signed_request, result.url); 
        //return callback(decodeURIComponent(result.signed_request), result.url); 
    

을 그리고 지금은 마법처럼 작동합니다! 이는 this SO solution과 매우 유사하며 s3upload.js 라이브러리에만 해당됩니다.

사이드 노트 - S3는 키 이름에 공백이있는 것처럼 보이지 않습니다. (아마존 설명서에서이 부분을 읽었습니다.) 나는 별개의 문제였습니다 ...