2009-09-01 9 views
14

Chiedersi se esiste un buon modo per generare URL temporanei che scadono in X giorni. Desidera inviare per posta elettronica un URL che il destinatario può fare clic per accedere a una parte del sito che non è accessibile tramite tale URL dopo un certo periodo di tempo. Non ho idea di come farlo, con Django, o Python o altro.Come generare URL temporanei in Django

risposta

15

Se non si prevede di ottenere un grande tasso di risposta, allora tu dovrebbe provare a memorizzare tutti i dati nell'URL stesso. In questo modo, non è necessario memorizzare nulla nel database e la memorizzazione dei dati sarà proporzionale alle risposte piuttosto che alle e-mail inviate.

Aggiornato: supponiamo che tu avessi due stringhe che erano uniche per ogni utente. È possibile imballare e decomprimerli con un hash proteggendo in questo modo:

import hashlib, zlib 
import cPickle as pickle 
import urllib 

my_secret = "michnorts" 

def encode_data(data): 
    """Turn `data` into a hash and an encoded string, suitable for use with `decode_data`.""" 
    text = zlib.compress(pickle.dumps(data, 0)).encode('base64').replace('\n', '') 
    m = hashlib.md5(my_secret + text).hexdigest()[:12] 
    return m, text 

def decode_data(hash, enc): 
    """The inverse of `encode_data`.""" 
    text = urllib.unquote(enc) 
    m = hashlib.md5(my_secret + text).hexdigest()[:12] 
    if m != hash: 
     raise Exception("Bad hash!") 
    data = pickle.loads(zlib.decompress(text.decode('base64'))) 
    return data 

hash, enc = encode_data(['Hello', 'Goodbye']) 
print hash, enc 
print decode_data(hash, enc) 

Questo produce:

849e77ae1b3c eJzTyCkw5ApW90jNyclX5yow4koMVnfPz09JqkwFco25EvUAqXwJnA== 
['Hello', 'Goodbye'] 

Nella tua e-mail, con un URL che ha sia i valori di hash ENC e (url- correttamente citato). Nella funzione di visualizzazione, utilizzare questi due valori con decode_data per recuperare i dati originali.

zlib.compress potrebbe non essere così utile, a seconda dei dati, è possibile sperimentare per vedere cosa funziona meglio per voi.

+0

Fondamentalmente ogni URL dovrebbe essere accessibile a un utente, quindi non un ampio tasso di risposta. Questa idea sembra interessante ma non riesco a ottenerla al 100%: un piccolo esempio sarebbe fantastico! – chacmool

3

È possibile impostare questo con URL del tipo:

http://yoursite.com/temp/1a5h21j32 

tuo URLconf sarebbe simile a questa:

from django.conf.urls.defaults import * 

urlpatterns = patterns('', 
    (r'^temp/(?P<hash>\w+)/$', 'yoursite.views.tempurl'), 
) 

... dove tempurl è un gestore di vista che recupera la pagina appropriata base sull'hash. Oppure, invia un 404 se la pagina è scaduta.

1

Dipende da ciò che si vuole fare: le operazioni one-shot come l'attivazione dell'account o il download di un file possono essere eseguite con una vista che ricerca un hash, controlla un timestamp ed esegue un'azione o fornisce un file .

Cose più complesse come la fornitura di dati arbitrari richiederebbero inoltre che il modello contenga un riferimento a tali dati in modo che sia possibile decidere cosa inviare indietro. Infine, consentire l'accesso a più pagine probabilmente implicherebbe l'impostazione di qualcosa nella sessione dell'utente e quindi l'utilizzo per determinare ciò che possono vedere, seguito da un reindirizzamento.

Se potessi fornire maggiori dettagli su cosa stai cercando di fare e quanto bene conosci Django, posso dare una risposta più specifica.

+0

Quello che voglio fare è fornire l'accesso a un modulo tramite l'URL temporaneo, in modo che il visitatore mirato possa andare all'URL entro X giorni (prima che il collegamento scada) e porterebbe il modulo. Il modulo sarebbe precompilato con dati che sarebbero diversi con ogni URL generato. Così stesso modulo, diversi dati per URL. – chacmool

5

modelli

class TempUrl(models.Model): 
    url_hash = models.CharField("Url", blank=False, max_length=32, unique=True) 
    expires = models.DateTimeField("Expires") 

Visto

def generate_url(request): 
    # do actions that result creating the object and mailing it 

def load_url(request, hash): 
    url = get_object_or_404(TempUrl, url_hash=hash, expires__gte=datetime.now()) 
    data = get_some_data_or_whatever() 
    return render_to_response('some_template.html', {'data':data}, 
           context_instance=RequestContext(request)) 

gli URL

urlpatterns = patterns('', url(r'^temp/(?P<hash>\w+)/$', 'your.views.load_url', name="url"),) 

// Naturalmente è necessario alcune importazioni e modelli

1

Penso che la soluzione risieda in una combinazione di tutte le soluzioni suggerite. Suggerirei di utilizzare una sessione in scadenza in modo che il collegamento scada entro il periodo di tempo specificato nel modello.Combinato con un reindirizzamento e un middleware per verificare se esiste un attributo di sessione e l'URL richiesto lo richiede, puoi creare parti del tuo sito un po 'sicure che possono avere URL più gradevoli che fanno riferimento a parti permanenti del sito. Lo uso per dimostrare design/funzionalità per un tempo limitato. Questo funziona per impedire l'inoltro ... Non lo faccio ma puoi rimuovere l'url temp dopo il primo clic in modo che solo l'attributo di sessione fornisca l'accesso in modo più efficace limitando a un utente. Personalmente non mi importa se l'url temp viene inoltrato sapendo che durerà solo per un certo periodo di tempo. Funziona bene in una forma modificata per tracciare anche le visite degli invitati.

+0

Interessante. Non sono sicuro di avere il metodo per impedire l'inoltro, mi piacerebbe sentire più dettagli su questo approccio. – chacmool

+0

ciò che intendo per inoltro è qualcuno che invia un link a qualcun altro. Puoi impostare il cookie una sola volta e contrassegnarlo nella tua app in modo tale che chiunque altro acceda all'URL non abbia accesso perché non ha il cookie. – mogga