How to prevent multiple login in Django
I think you make things very complicated, by storing data in UserProfile
s, etc. and then have signals, you introduce a lot of levels, and at each level, things can go wrong.
We basically need two things here: a table that maps User
s to their corresponding settings. We can implement this with a UserSession
model:
# models.py
from django.conf import settings
from django.db import models
from django.contrib.sessions.models import Session
class UserSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
session = models.OneToOneField(Session, on_delete=models.CASCADE)
So the UserSession
object makes a link between User
and Session
s. Now we can implement a login hook: a signal that is triggered in case a user logs in. In that case we perform two things:
- we delete all
Session
s (and correspondingUserSession
s) of theUser
that are active; and - we create a new
Session
and correspondingUserSession
that we can remove later. Like:
from django.contrib.auth import user_logged_in
from django.dispatch.dispatcher import receiver
@receiver(user_logged_in)
def remove_other_sessions(sender, user, request, **kwargs):
# remove other sessions
Session.objects.filter(usersession__user=user).delete()
# save current session
request.session.save()
# create a link from the user to the current session (for later removal)
UserSession.objects.get_or_create(
user=user,
session=Session.objects.get(pk=request.session.session_key)
)