Wie kann ich mehrere Anmeldungen in eine Django Web-Anwendung von verschiedenen Standorten erkennen?
-
03-07-2019 - |
Frage
Ich möchte nur eine authentifizierte Sitzung zu einem Zeitpunkt für einen individuellen Login in meiner Django-Anwendung ermöglichen. Also, wenn ein Benutzer in die Webseite auf eine bestimmte IP-Adresse angemeldet ist, und die gleichen Benutzerdaten von einer anderen IP-Adresse anmelden verwendet, ich will etwas tun (entweder abzumelden den ersten Benutzer oder verweigern den Zugriff auf den zweiten Benutzer.)
Lösung
Nicht sicher, ob dies noch erforderlich ist, aber dachte, ich würde meine Lösung teilen:
1) Installieren Sie django-Tracking (thankyou für die Spitze Van Gale Google Maps + GeoIP ist erstaunlich!)
2) Fügen Sie diese Middleware:
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, es geht nach dem VisitorTrackingMiddleware und Sie sollten vorherige Anmeldungen finden werden automatisch gestoßen, wenn jemand neu anmeldet:)
Andere Tipps
Wenn Sie bereits verwenden django-Tracking wie hier vorgeschlagen, gibt es einen viel einfacheren Weg, dies zu implementieren:
Definieren Sie einen Signal-Handler:
# 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 user_logged_in Signal:
# 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)
Dies wird eine Art einzuleiten Systems „letzten Benutzer gewinnt Login“. Wenn Sie mehrere Logins durch denselben Nutzer von derselben IP zulassen möchten, können Sie eine .exclude()
zum Visitors
Lookup hinzuzufügen.
Middleware wahrscheinlich helfen Sie dies erreichen. Das Problem ist, dass Sie wahrscheinlich mehr anonymen Sitzungen von derselben IP-Adresse, auch authentifizierte Sitzungen für verschiedene Benutzer ermöglichen will, aber nicht authentifizierten Sitzungen für denselben Benutzer.
Sie wollen:
-
Erstellen Sie ein Benutzerprofil-Modell die IP-Adresse eines Benutzers letzten Login zu speichern. Siehe Djangos Speichern von zusätzlichen Informationen über die Nutzer Dokumentation.
-
Implementieren eines benutzerdefinierten Authentifizierungs-Backend . Dieses Backend, wenn sie ausgelöst wird und die Authentifizierung erfolgreich einen Benutzer (einfach super nennen) würde die Benutzer letzten Login IP im Profilmodell auszulöschen.
-
Implementieren einer Unterklasse von Djangos
django.contrib.sessions.SessionMiddleware
Klasse. Implementieren Sieprocess_request
. Wenn das Profil Modellrequest.user
Objekt keine IP-Adresse verfügt, stellen Sie bitte die Anfrage erlauben. Wenn es eine IP hat, und die IP unterscheidet sich von der IP (request.META.REMOTE_ADDR
) der aktuellen Anforderung, dann tun, was Sie entweder wie die anderen Benutzer abzumelden oder einen Fehler zurück an den Anforderer. -
Aktualisieren Sie Ihre
settings.py
Datei, so dass Ihre benutzerdefinierten Authentifizierungs-Backend zuerst verarbeitet wird, und so, dass Ihre benutzerdefinierten Session-Middleware auch zuerst verarbeitet wird. Dies beinhaltetsettings.AUTHENTICATION_BACKENDS
undsettings.MIDDLEWARE_CLASSES
zu aktualisieren.
Sie werden diese mit eigenen Middleware müssen tun.
In Ihrer Middleware process_request()
Methode haben Sie Zugriff auf das Request-Objekt, so dass Sie so etwas wie die folgenden Möglichkeiten:
session_key = request.session.session_key
ip_address = request.META.get('REMOTE_ADDR', '')
Jetzt wissen Sie, die IP-Adresse, so überprüfen Sie ein Modell erstellen Sie, dass (in etwa) würde wie folgt aussehen:
class SessionIPS(models.Model):
session = models.ForeignKey(Session)
IP = models.CharField(max_length=20)
So, wenn eine Sitzung erstellt oder gelöscht werden Sie Ihre Sitzung ip die Tabelle entsprechend modifizieren, und wenn eine Anforderung der IP-Adresse kommt sicher nicht für eine weitere Sitzung verwendet wird. Wenn, wenn, dann zurückgeben Http404 (oder so ähnlich) von der Middleware.
Eine steckbare App, die Ihnen viel mehr Detail zeigen kann (und umfasst auch die IP-Adresse in seinem eigenen Modell) ist django-Tracking .