如何从不同位置检测到多个登录到Django Web应用程序?

Mik*_*keN 24 django django-authentication

我想一次只允许一个经过身份验证的会话,以便在我的Django应用程序中进行单独登录.因此,如果用户登录到给定IP地址的网页,并且使用相同的用户凭据从不同的IP地址登录,我想做某事(登出第一个用户或拒绝访问第二个用户.)

小智 19

不确定这是否仍然需要,但我想我会分享我的解决方案:

1)安装django-tracking(谢谢你的提示Van Gale Google Maps + GeoIP太棒了!)

2)添加此中间件:

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()
Run Code Online (Sandbox Code Playgroud)

3)确保它在VisitorTrackingMiddleware之后,你应该发现当有人新登录时,以前的登录会自动碰到:)


Dan*_*inn 10

如果你已经按照这里的建议使用django-tracking,那么有一种更简单的方法来实现它:

定义信号处理程序:

# 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()
Run Code Online (Sandbox Code Playgroud)

为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)
Run Code Online (Sandbox Code Playgroud)

这将构成一种"最后用户登录获胜"系统.如果要允许同一用户从同一个ip进行多次登录,可以.exclude()Visitors查找中添加一个.


Jar*_*die 7

Django的中间件可能会帮助您实现这一目标.问题是您可能希望允许来自同一IP地址的多个匿名会话,甚至是针对不同用户的经过身份验证的会话,但不允许同一用户的经过身份验证的会话.

你想要:

  1. 创建用户配置文件模型以存储用户上次登录的IP地址.请参阅Django的存储有关用户文档的其他信息.

  2. 实现自定义身份验证后端.当触发并成功验证用户(仅调用超级用户)时,此后端将消除用户在配置文件模型中的最后一次登录IP.

  3. 实现Django django.contrib.sessions.SessionMiddleware类的子类.实施process_request.如果request.user对象的配置文件模型没有IP地址,请设置它并允许该请求.如果它具有IP,并且IP与当前请求的IP(request.META.REMOTE_ADDR)不同,则执行您喜欢的任何操作以注销其他用户,或者向请求者返回错误.

  4. 更新您的settings.py文件,以便首先处理您的自定义身份验证后端,以便首先处理您的自定义会话中间件.这包括更新settings.AUTHENTICATION_BACKENDSsettings.MIDDLEWARE_CLASSES.


Van*_*ale 6

您需要使用自定义中间件执行此操作.

在您的中间件process_request()方法中,您将可以访问请求对象,以便您可以执行以下操作:

session_key = request.session.session_key
ip_address = request.META.get('REMOTE_ADDR', '')
Run Code Online (Sandbox Code Playgroud)

现在您知道了IP地址,因此请检查您创建的模型(粗略地)如下所示:

class SessionIPS(models.Model):
    session = models.ForeignKey(Session)
    IP = models.CharField(max_length=20)
Run Code Online (Sandbox Code Playgroud)

因此,当创建或删除会话时,您将相应地修改会话ip的表,并在请求进入时确保IP地址未用于另一个会话.如果是,则从中间件返回Http404(或类似的东西).

可插拔的应用程序可以显示更多细节(甚至包括自己模型中的IP地址)是django-tracking.