2009-09-01 28 views
14

Ich frage mich, ob es eine gute Möglichkeit gibt, temporäre URLs zu generieren, die in X Tagen ablaufen. Möchten Sie eine URL per E-Mail versenden, auf die der Empfänger klicken kann, um auf einen Teil der Site zuzugreifen, der nach einiger Zeit nicht mehr über diese URL erreichbar ist. Keine Ahnung wie man das macht, mit Django oder Python oder anders.So generieren Sie temporäre URLs in Django

Antwort

15

Wenn Sie nicht zu bekommen, erwarten eine große Rücklaufquote, dann Sie sollte versuchen, alle Daten in der URL selbst zu speichern. Auf diese Weise müssen Sie nichts in der Datenbank speichern und haben einen Datenspeicher, der proportional zu den Antworten und nicht zu den gesendeten E-Mails ist.

Aktualisiert: Angenommen, Sie hatten zwei Zeichenfolgen, die für jeden Benutzer eindeutig waren. Sie können sie packen und entpacken mit einem Schutz Hash wie folgt aus:

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) 

Dies erzeugt: sowohl den Hash und enc Werte

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

In Ihrer E-Mail eine URL, die (eigentlich hat URL- zitiert). Verwenden Sie in Ihrer Ansichtsfunktion diese beiden Werte mit decode_data, um die ursprünglichen Daten abzurufen.

Die zlib.compress ist möglicherweise nicht so hilfreich, abhängig von Ihren Daten können Sie experimentieren, um zu sehen, was für Sie am besten funktioniert.

+0

Grundsätzlich wäre jeder URL für einen Benutzer zugänglich, also keine große Antwortrate. Diese Idee klingt interessant, aber ich bekomme sie nicht 100% - ein kleines Beispiel wäre großartig! – chacmool

3

Sie könnten dies einrichten mit URLs wie:

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

Ihr URLconf etwas würde wie folgt aussehen:

from django.conf.urls.defaults import * 

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

... wo tempurl eine Ansicht Handler ist, der die entsprechende Seite holt basierend auf dem Hash. Oder sendet eine 404, wenn die Seite abgelaufen ist.

1

Es hängt davon ab, was Sie tun möchten - einmalige Aktionen wie Kontoaktivierung oder das Herunterladen einer Datei können mit einer Ansicht durchgeführt werden, die einen Hashwert überprüft, einen Zeitstempel überprüft und eine Aktion ausführt oder eine Datei bereitstellt .

Bei komplexeren Daten wie der Bereitstellung beliebiger Daten müsste das Modell auch einen Verweis auf diese Daten enthalten, damit Sie entscheiden können, was Sie zurücksenden möchten. Schließlich würde das Zulassen des Zugriffs auf mehrere Seiten wahrscheinlich beinhalten, etwas in der Sitzung des Benutzers zu setzen und dann zu bestimmen, was sie sehen können, gefolgt von einer Weiterleitung.

Wenn Sie mehr Details darüber, was Sie zu tun versuchen und wie gut Sie wissen, Django, kann ich eine genauere Antwort geben.

+0

Was ich tun möchte, ist der Zugriff auf ein Formular über die temporäre URL, so dass der anvisierte Besucher innerhalb von X Tagen (bevor der Link abläuft) zur URL gehen und das Formular aufrufen würde. Das Formular wird mit Daten gefüllt, die sich bei jeder generierten URL unterscheiden. Also gleiche Form, unterschiedliche Daten pro URL. – chacmool

5

Modelle

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

Ansichten

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)) 

Urls

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

// natürlich müssen Sie einige Importe und Vorlagen

1

Ich denke, die Lösung liegt in einer Kombination aller vorgeschlagenen Lösungen. Ich würde vorschlagen, eine ablaufende Sitzung zu verwenden, damit der Link innerhalb des Zeitraums, den Sie im Modell angeben, abläuft.Kombiniert mit einer Weiterleitung und Middleware, um zu prüfen, ob ein Sitzungsattribut existiert und die angeforderte URL es erfordert, können Sie etwas sichere Teile Ihrer Site erstellen, die schönere URLs haben, die auf permanente Teile der Site verweisen. Ich nutze dies, um Design/Funktionen für eine begrenzte Zeit zu demonstrieren. Dies funktioniert, um die Weiterleitung zu verhindern ... Ich mache es nicht, aber Sie könnten die temporäre URL nach dem ersten Klick entfernen, so dass nur das Sitzungsattribut den Zugriff ermöglicht und somit effektiver auf einen Benutzer beschränkt ist. Mir persönlich macht es nichts aus, wenn die temporäre URL weitergeleitet wird, obwohl sie weiß, dass sie nur für eine bestimmte Zeit anhält. Funktioniert auch in modifizierter Form für die Verfolgung von eingeladenen Besuchen.

+0

Interessant. Ich bin mir nicht sicher, ob ich die Methode zur Verhinderung der Weiterleitung bekomme, würde es lieben, mehr Details zu diesem Ansatz zu hören. – chacmool

+0

was ich mit Weiterleitung meine, ist jemand, der einen Link an jemand anderen sendet. Sie legen den Cookie einmal fest und kennzeichnen ihn in Ihrer App so, dass alle anderen Personen, die auf die URL zugreifen, keinen Zugriff haben, da sie das Cookie nicht haben. – mogga