2012-10-19 14 views
5

Ich habe eine Django-App, mit der Benutzer MP3-Dateien herunterladen können, die sie gekauft haben, und diese MP3-Dateien werden in Amazon S3 gehostet. Wie kann ich einen Download erzwingen, wenn Benutzer auf einen "Download" -Button klicken, ohne dass sie den ursprünglichen Link (zu Amazon) sehen können? Ich habe eine Ansicht, die die Datei herunterlädt, aber die Datei ist beschädigt. Hier ist, wie es aussieht:Herunterladen von Dateien von Amazon S3 mit Django

def download(request): 
    filename = 'https://s3-eu-west-1.amazonaws.com/skempi/Ihsahn/04-emancipation-qtxmp3.mp3' 
    response = HttpResponse(mimetype='application/force-download') 
    response['Content-Disposition']='attachment;filename="%s"'%filename 
    response["X-Sendfile"] = filename 
    return response 
+1

Haben Sie das überprüfen? https://forums.aws.amazon.com/message.jspa?messageID=257743 – sergzach

Antwort

6

Wenn Sie zum Download sein die Dateien nicht möchten, setzen Sie ACL privat (nur über Ihr Konto) zu sein. Ihre Benutzer können Dateien immer noch herunterladen, wenn Sie ihnen eine signierte URL zur Verfügung stellen. Wenn Sie eine URL signieren, generieren Sie ein Token mit Ablaufzeit. Sie können es zu etwas vernünftigem als 10 Minuten einstellen. Verwenden Sie Amazon Web Services interface for Python — Boto.

import boto 
conn = boto.connect_s3('<aws access key>', '<aws secret key>') 
bucket = conn.get_bucket('your_bucket') 
s3_file_path = bucket.get_key('path/to/file') 
url = s3_file_path.generate_url(expires_in=600) # expiry time is in seconds 

return HttpResponseRedirect(url) 

Beachten Sie, dass dies sicher ist, ist als Token nur nur gültig für eine Request-Methode (GET Standardeinstellung) und nur für eine Datei. Es besteht also kein Risiko, dass jemand das Token wiederverwendet, um beispielsweise andere Dateien herunterzuladen oder die angegebene Datei zu manipulieren.

+0

Ich habe versucht, dies aber nach 'Eimer = conn.get_bucket ('my_bucket')' Ich erhalte eine 'S3ResponseError: S3ResponseError: 403 Forbidden' Fehler und in dem Message-Tag gibt es 'den Unterschied zwischen der Anforderungszeit und der aktuellen Zeit ist zu large.' –

+0

@Mohamed: die Zeit auf dem lokalen Rechner ist nicht synchron. Sie sollten die automatische Synchronisierung beispielsweise mit [NTP] (http://en.wikipedia.org/wiki/Network_Time_Protocol) einrichten. – vartec

+0

ich den gleichen Fehler, wenn ich versuchen AS3 zu verwenden, um Dateien aus dem Django-Admin-Panel zu laden, denken Sie, das Problem ist immer noch mit der Zeit –

6

Ich konnte nicht einfach finden, wo angegeben, wie dies zu tun und endete wieder bei dieser Frage immer wieder, wenn ich suchte. So

Mit django-Speicher der boto Backend verwenden, die Art und Weise, dies zu tun, ist so etwas wie

filepath = settings.MEDIA_DIRECTORY + file.name 
response_headers = { 
    'response-content-type': 'application/force-download', 
    'response-content-disposition':'attachment;filename="%s"'%file.name 
    } 
url = s3.generate_url(60, 'GET', 
       bucket=settings.AWS_STORAGE_BUCKET_NAME, 
       key=filepath, 
       response_headers=response_headers, 
       force_http=True) 
return http.HttpResponseRedirect(url) 
+3

Ich habe entdeckt, dass dies derzeit in Django-Speicher eingebaut ist. Nach Ihrem obigen Beispiel kann dies als erreicht werden: 'url = storage.url (filepath, headers = response_headers)' – robhudson

Verwandte Themen