How to prevent multiple login in Django

前端 未结 2 1658
我寻月下人不归
我寻月下人不归 2020-12-06 07:50

I\'m writing a User system that cannot login at the same time. If the account in login state in somewhere, and someone login the same account in other position. The latter o

相关标签:
2条回答
  • 2020-12-06 08:19

    I think you make things very complicated, by storing data in UserProfiles, 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 Users 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 Sessions. 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:

    1. we delete all Sessions (and corresponding UserSessions) of the User that are active; and
    2. we create a new Session and corresponding UserSession 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)
        )
    0 讨论(0)
  • 2020-12-06 08:19

    Since you want the user to have only one session at a time, you can call logout before you call login

    ...
    if user is not None and user.is_active:
        auth.logout(request)
        auth.login(request, user)
    

    Logout documentation: https://docs.djangoproject.com/en/3.0/topics/auth/default/#django.contrib.auth.logout

    0 讨论(0)
提交回复
热议问题