2015-09-04 24 views
6

Attualmente, il mio file index.html contieneCome fornire URL di download temporaneo in Flask?

<a href="static/file.ext">Download</a> 

voglio cambiare questo in modo che l'URL per il download è valido solo per un certo periodo di tempo. Ad esempio, come potrei cambiare a

<a href="get_file?file=file.ext&token=TEMPORARYTOKEN">Download</a> 

Nel mio file Flask, ho potuto quindi avere

@app.route('/get_file') 
def get_file(): 
    filename = request.args.get('file') 
    token = request.args.get('token') 
    if token is valid: # what can be done here 
     return send_from_directory('static', filename) 

Come posso generare e gestire il token? O mi sto avvicinando a questo completamente sbagliato?

+0

Mentre penso che la tua domanda è corretta, ho voluto discutere una cosa relative a questo. Proprio a causa di questo vincolo, costringeremo il framework (django/flask/RoR) allo streaming del file, mentre mi sarebbe piaciuto se ci fosse una soluzione in cui potremmo ottenere nginx/apache per servirlo. – darkryder

+0

Esiste un modo migliore per fornire l'autenticazione temporanea per i download utilizzando nginx o apache? Come comunicarebbe con il resto del programma? – Kootling

+0

Che struttura stai usando? – darkryder

risposta

3

Ci sono un paio di modi per farlo.

  1. Generare un UUID per il token e memorizzarlo in una tabella db insieme alla scadenza desiderata datetime. Quindi, quando qualcuno chiama l'URL con il token, puoi semplicemente verificarlo con il db per validità e scadenza.

  2. Se non si desidera utilizzare un db per memorizzare i token, è possibile utilizzare GPG per crittografare una stringa che contiene la scadenza datetime e utilizzare la stringa crittografata risultante come token. Ciò significa che il tuo token sarà molto più lungo di un UUID, ma eviterai di dover usare un db.

Si consiglia di utilizzare UUID e una tabella db.

0

Un altro modo sarebbe quello di codificare la chiave primaria dal db in base64. Questo è il modo in cui i servizi di url brevi in ​​tutta la rete ricevono gli URL brevi. Il db garantisce l'unicità e dal momento che è base64 ci vorranno parecchi file prima che gli URL crescano a lungo.

Ad ogni richiesta, quindi controllare il db per vedere se il collegamento è ancora valido. Se non lo fai, fai qualcosa di significativo con la richiesta.

3

Forse dovresti usare hmac.

Genera collegamento

import hashlib 
import hmac 
import time 
secret = "anything you like" # such as generate from os.urandom(length) 
def generate(filename): 
    current_time = str(int(time.time())) 
    token = hmac.new(secret, current_time, hashlib.sha256).hexdigest() 
    return "get_file?file=%(filename)s&time=%(current_time)s&token=%(token)s" % { 
     "filename": filename, 
     "current_time": current_time, 
     "token": token 
    } 

Verifica collegamento

import hashlib 
import hmac 
import time 
secret = "anything you like" # same as in generate function 
def verify(time_in_link, token_in_link): 
    time_limit = 15 * 60 # maximum time in sec(such as: 15(mins) * 60 (convert them to sec)`enter code here`) that you want them to start download after the link has been generated. 
    if (time.time() - int(time_in_link)) > time_limit: #timeout, return False 
     return False 
    if hmac.new(secret, str(time_in_link), hashlib.sha256).hexdigest() == token_in_link: # Check the token is available or not 
     return True 
    else: 
     return False