vincent - register and login django
¿Cómo puedo detectar varios inicios de sesión en una aplicación web de Django desde diferentes ubicaciones? (4)
El middleware de Django probablemente te ayudará a lograr esto. El problema es que probablemente desee permitir varias sesiones anónimas desde la misma dirección IP, incluso sesiones autenticadas para diferentes usuarios, pero no sesiones autenticadas para el mismo usuario.
Querrás:
Cree un modelo de perfil de usuario para almacenar la dirección IP del último inicio de sesión de un usuario. Ver Django''s Almacenamiento de información adicional sobre la documentación de los usuarios .
Implementar un backend de autenticación personalizado . Este backend, cuando se activa y autentica correctamente a un usuario (simplemente llame a super) borrará la última IP de inicio de sesión del usuario en el modelo de perfil.
Implementar una subclase de la clase
django.contrib.sessions.SessionMiddleware
de Django. Implementarprocess_request
. Si el modelo de perfil del objetorequest.user
no tiene una dirección IP, configúrelo y permita la solicitud. Si tiene una dirección IP y la dirección IP es diferente de la dirección IP de la solicitud actual (request.META.REMOTE_ADDR
), haga lo que desee para desconectarse del otro usuario o devolver un error al solicitante.Actualice su archivo
settings.py
para que su back-end de autenticación personalizada se procese primero, y para que su middleware de sesión personalizado también se procese primero. Esto implica la actualización de lassettings.AUTHENTICATION_BACKENDS
ysettings.MIDDLEWARE_CLASSES
.
Solo quiero permitir una sesión autenticada a la vez para un inicio de sesión individual en mi aplicación Django. Entonces, si un usuario inicia sesión en la página web en una dirección IP determinada, y esas mismas credenciales de usuario se usan para iniciar sesión desde una dirección IP diferente, quiero hacer algo (ya sea desconectar al primer usuario o denegar el acceso al segundo usuario).
No estoy seguro si esto todavía es necesario pero pensé que compartiría mi solución:
1) Instalar django-tracking (gracias por ese consejo Van Gale Google Maps + GeoIP es increíble!)
2) Agregue este 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) Asegúrate de que va después del VisitorTrackingMiddleware y deberías encontrar inicios de sesión previos que se golpean automáticamente cuando alguien nuevo inicia sesión :)
Si ya está usando django-tracking como se sugiere aquí, hay una forma mucho más sencilla de implementar esto:
Definir un manejador de señal:
# 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()
Crea un oyente para la señal 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)
Esto instituirá una especie de sistema de "último usuario para iniciar sesión". Si desea permitir múltiples inicios de sesión por el mismo usuario desde la misma ip, puede agregar un .exclude()
a la búsqueda de Visitors
.
Tendrá que hacer esto con middleware personalizado.
En su método middleware process_request()
tendrá acceso al objeto de solicitud para que pueda hacer algo como lo siguiente:
session_key = request.session.session_key
ip_address = request.META.get(''REMOTE_ADDR'', '''')
Ahora conoces la dirección IP, así que verifica un modelo que crees que (más o menos) se vería así:
class SessionIPS(models.Model):
session = models.ForeignKey(Session)
IP = models.CharField(max_length=20)
Por lo tanto, cuando se crea o se elimina una sesión, se modificará la tabla de la sesión de la IP en consecuencia, y cuando se presente una solicitud, asegúrese de que la dirección IP no se esté utilizando para otra sesión. Si es así, devuelva un Http404 (o algo similar) del middleware.
Una aplicación conectable que puede mostrarle muchos más detalles (e incluso incluye la dirección IP en su propio modelo) es django-tracking .