2012-10-19 21 views
5

Ho un'app Django che consente agli utenti di scaricare i file MP3 che hanno acquistato e questi file MP3 sono ospitati su Amazon S3. Come posso forzare un download quando gli utenti fanno clic su un pulsante "download" senza consentire loro di vedere il link originale (in Amazon)? Ho una vista che scarica il file ma il file è corrotto. Ecco come sembra:Scarica file da Amazon S3 con 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

Avete controllare questo fuori? https://forums.aws.amazon.com/message.jspa?messageID=257743 – sergzach

risposta

6

Se non si desidera che i file siano scaricabili, impostare ACL per essere privata (accessibile solo tramite il vostro account). I tuoi utenti saranno ancora in grado di scaricare file se fornisci loro un URL firmato. Quando si firma un URL, si genera token con scadenza. Puoi impostarlo su qualcosa di ragionevole come 10 minuti. Utilizzare 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) 

Nota, che questo è sicuro, come token è valido solo per un solo metodo di richiesta (GET per impostazione predefinita) e solo per un unico file. Quindi non c'è il rischio che qualcuno riutilizzi il token, ad esempio scaricare altri file o manipolare il file dato.

+0

Ho provato questo, ma dopo 'bucket = conn.get_bucket ('my_bucket')' Ricevo un errore 'S3ResponseError: S3ResponseError: 403 Forbidden' e nel tag messaggio c'è 'La differenza tra il tempo di richiesta e l'ora corrente è troppo grande. –

+0

@Mohamed: l'ora sul tuo computer locale non è sincronizzata. È necessario impostare la sincronizzazione automatica utilizzando, ad esempio, [NTP] (http://en.wikipedia.org/wiki/Network_Time_Protocol). – vartec

+0

Ricevo lo stesso errore quando provo ad usare AS3 per caricare file dal pannello di amministrazione Django, pensi che il problema sia ancora nel momento in cui non è sincronizzato. –

6

Non riuscivo facilmente a trovare da nessuna parte che specificasse come fare questo e sono tornato indietro a questa domanda più e più volte quando ho cercato. Così

Con django-depositi utilizzando il backend boto, il modo per farlo è qualcosa di simile

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

Ho scoperto che questo è attualmente integrato negli archivi di django. Seguendo il tuo esempio precedente, questo può essere compiuto come: 'url = storage.url (filepath, headers = response_headers)' – robhudson