Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent multiple logins using the same credentials

I checked previously asked similar Questions, but I am not able to find a suitable answer.

Requirement: On two different machines the same user credentials can't be used to access the application.

What I have implemented, At the time of login, logout from all previous devices used by user.

from django.contrib.auth.signals import user_logged_in

class UserAccount(models.Model):
    """
    This model will be used to extra user information.
    """

    user = models.OneToOneField(User, db_index=True)
    session = models.CharField(max_length=40, null=True)
    ip_address = models.IPAddressField()

def logout_other_devices(user, request, **kwargs):
    """
    Delete session(logout all) other devices with same credential.
    """

    profile = user.useraccount

    if profile.session:
        Session.objects.filter(session_key=profile.session).delete()

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


user_logged_in.connect(logout_other_devices)

What still is left, if one user is logged in one system and passes its sessionid (from cookies) to the second user connected under the same WiFi(or LAN) connection then the IP of second is coming same on server. How can I discriminate the second user and log-out the first user before allowing access to any website data to the second user.

like image 444
Ankit Sachdeva Avatar asked Jun 17 '26 23:06

Ankit Sachdeva


1 Answers

Django generates a session key and saves it in the db everytime a user logs in. If user logs in from another browser/device Django creates a new session key without deleting the old one.

If you want to log the user out of other devices, you just need to delete his/her previous session key from db.

Since there is no easy way to identify which key belongs to which user, you will have to save the session key in user model after the user logs in. So, add another field in your User model called session_key, like so:

# models.py

class UserAccount(...):
    ...
    session_key = models.CharField(max_length=100, null=True)

You will also need to make some changes to your login view, like so:

# views.py

from django.contrib.sessions.backend.db import Session

def login_view(request):
    ...
    user = authenticate(...)
    
    # Here comes good part

    if user is not None:

        if user.session_key: # check if user has session_key. This will be true for users logged in on another device
            try:
                s = Session.objects.get(session_key=user.session_key)
            except Session.DoesNotExist:
                pass
            else:
                s.delete() # delete the old session_key from db

       login(request, user) # log the user in

       # set new session_key for user instance
       user.session_key = request.session.session_key
       user.save() # save the user

    # do other stuff
like image 90
xyres Avatar answered Jun 19 '26 13:06

xyres