32 Stimmen

Wie kann ich mehrere Anmeldungen bei einer Django-Webanwendung von verschiedenen Standorten aus erkennen?

Ich möchte nur eine authentifizierte Sitzung zu einer Zeit für eine einzelne Anmeldung in meiner Django-Anwendung zu ermöglichen. Wenn also ein Benutzer auf der Webseite mit einer bestimmten IP-Adresse angemeldet ist und dieselben Benutzerdaten für die Anmeldung von einer anderen IP-Adresse aus verwendet werden, möchte ich etwas tun (entweder den ersten Benutzer abmelden oder dem zweiten Benutzer den Zugriff verweigern).

24voto

Ich bin mir nicht sicher, ob das noch gebraucht wird, aber ich dachte, ich würde meine Lösung mitteilen:

1) Installieren Sie django-tracking (vielen Dank für diesen Tipp Van Gale Google Maps + GeoIP ist großartig!)

2) Fügen Sie diese Middleware hinzu:

from django.contrib.sessions.models import Session
from tracking.models import Visitor
from datetime import datetime

class UserRestrictMiddleware(object):
    """
    Prevents more than one user logging in at once from two different IPs
    """
    def process_request(self, request):
        ip_address = request.META.get('REMOTE_ADDR','')
        try:
            last_login = request.user.last_login
        except:
            last_login = 0
        if unicode(last_login)==unicode(datetime.now())[:19]:
            previous_visitors = Visitor.objects.filter(user=request.user).exclude(ip_address=ip_address)
            for visitor in previous_visitors:
                Session.objects.filter(session_key=visitor.session_key).delete()
                visitor.user = None
                visitor.save()

3) Stellen Sie sicher, dass es nach der VisitorTrackingMiddleware geht und Sie sollten feststellen, dass frühere Anmeldungen automatisch gelöscht werden, wenn sich jemand neu anmeldet :)

10voto

Daniel Quinn Punkte 5326

Wenn Sie bereits django-tracking wie hier vorgeschlagen verwenden, gibt es einen viel einfacheren Weg, dies zu implementieren:

Definieren Sie einen Signalhandler:

# myapp/signals.py
def kick_my_other_sessions(sender, request=None, user=None, **kwargs):
    from tracking.models import Visitor
    from django.contrib.sessions.models import Session
    keys = [v.session_key for v in Visitor.objects.filter(user=request.user).exclude(session_key=request.session.session_key)]
    Session.objects.filter(session_key__in=keys).delete()

Erstellen Sie einen Listener für das Signal user_logged_in:

# myapp/__init__.py
from myapp.signals import kick_my_other_sessions
from django.contrib.auth.signals import user_logged_in
user_logged_in.connect(kick_my_other_sessions, sender=User)

Dadurch wird eine Art "der zuletzt angemeldete Benutzer gewinnt" System eingeführt. Wenn Sie mehrere Anmeldungen desselben Benutzers von derselben IP-Adresse aus zulassen möchten, können Sie eine .exclude() zum Visitors Nachschlagen.

7voto

Jarret Hardie Punkte 89900

Djangos Middleware wird Ihnen wahrscheinlich helfen, dies zu erreichen. Das Problem ist, dass Sie wahrscheinlich mehrere anonyme Sitzungen von derselben IP-Adresse aus zulassen wollen, sogar authentifizierte Sitzungen für verschiedene Benutzer, aber keine authentifizierten Sitzungen für denselben Benutzer.

Das werden Sie wollen:

  1. Erstellen Sie ein Benutzerprofilmodell, um die IP-Adresse der letzten Anmeldung eines Benutzers zu speichern. Siehe Djangos Speicherung zusätzlicher Informationen über Benutzer Dokumentation.

  2. Umsetzung einer benutzerdefiniertes Authentifizierungs-Backend . Dieses Backend würde, wenn es ausgelöst wird und einen Benutzer erfolgreich authentifiziert (rufen Sie einfach super auf), die letzte Anmelde-IP des Benutzers im Profilmodell auslöschen.

  3. Implementieren Sie eine Unterklasse von Djangos django.contrib.sessions.SessionMiddleware Klasse. Implementieren Sie process_request . Wenn die request.user Objekts keine IP-Adresse hat, setzen Sie diese und erlauben Sie die Anfrage. Wenn es eine IP-Adresse hat und diese sich von der IP-Adresse der aktuellen Anfrage unterscheidet ( request.META.REMOTE_ADDR ), dann tun Sie, was immer Sie wollen, um entweder den anderen Benutzer abzumelden oder einen Fehler an den Anfragenden zurückzugeben.

  4. Aktualisieren Sie Ihr settings.py Datei, so dass Ihr benutzerdefiniertes Authentifizierungs-Backend zuerst verarbeitet wird und dass Ihre benutzerdefinierte Sitzungs-Middleware ebenfalls zuerst verarbeitet wird. Dies beinhaltet das Aktualisieren settings.AUTHENTICATION_BACKENDS y settings.MIDDLEWARE_CLASSES .

6voto

Van Gale Punkte 42727

Sie müssen dies mit benutzerdefinierter Middleware tun.

In Ihrer Middleware process_request() Methode haben Sie Zugriff auf das Request-Objekt, so dass Sie etwas wie das Folgende tun können:

session_key = request.session.session_key
ip_address = request.META.get('REMOTE_ADDR', '')

Da Sie nun die IP-Adresse kennen, können Sie ein Modell erstellen, das (grob) wie folgt aussehen würde:

class SessionIPS(models.Model):
    session = models.ForeignKey(Session)
    IP = models.CharField(max_length=20)

Wenn also eine Sitzung erstellt oder gelöscht wird, ändern Sie die Tabelle der Sitzungs-IPs entsprechend, und wenn eine Anfrage eingeht, stellen Sie sicher, dass die IP-Adresse nicht für eine andere Sitzung verwendet wird. Wenn ja, dann geben Sie einen Http404 (oder etwas ähnliches) von der Middleware zurück.

Eine ansteckbare Anwendung, die Ihnen viel mehr Details zeigen kann (und sogar die IP-Adresse in ihr eigenes Modell einbezieht), ist django-tracking .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X