简体   繁体   English

防止使用相同凭据进行多次登录

[英]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.还剩下什么,如果一个用户登录一个系统并将其sessionid (来自 cookie)传递给在同一 WiFi(或 LAN)连接下连接的第二个用户,那么第二个 IP 在服务器上是相同的。 How can I discriminate the second user and log-out the first user before allowing access to any website data to the second user.在允许第二个用户访问任何网站数据之前,我如何区分第二个用户并注销第一个用户。

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.每次用户登录时,Django 都会生成一个会话密钥并将其保存在数据库中。如果用户从另一个浏览器/设备登录,Django 会创建一个新的会话密钥而不删除旧的会话密钥。

If you want to log the user out of other devices, you just need to delete his/her previous session key from db.如果你想让用户退出其他设备,你只需要从 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:由于没有简单的方法来确定哪个密钥属于哪个用户,因此在用户登录后,您必须将会话密钥保存在用户模型中。因此,在用户模型中添加另一个名为session_key字段,如下所示:

# 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

This is should work over here这应该在这里工作

#models.py #models.py

from django.contrib.sessions.models import Session

class UserSession(models.Model):
    user_acc = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    session_maneger = models.OneToOneField(Session, on_delete=models.CASCADE)

#views.py #views.py

from django.contrib.auth import user_logged_in
from django.dispatch.dispatcher import receiver
from django.contrib.sessions.models import Session
from .models import UserSession

@receiver(user_logged_in)
def remove_other_sessions(sender, user, request, **kwargs):
    Session.objects.filter(usersession__user=user).delete() # removing user other session

    request.session.save() # here is the saving users current session

    # 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)
    )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM