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

发布于 2024-07-18 08:04:21 字数 125 浏览 4 评论 0原文

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

I want to only allow one authenticated session at a time for an individual login in my Django application. So if a user is logged into the webpage on a given IP address, and those same user credentials are used to login from a different IP address I want to do something (either logout the first user or deny access to the second user.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜味超标? 2024-07-25 08:04:21

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

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

3)确保它在VisitorTrackingMiddleware,您应该会发现当有人新登录时,以前的登录会自动被撞到:)

Not sure if this is still needed but thought I would share my solution:

1) Install django-tracking (thankyou for that tip Van Gale Google Maps + GeoIP is amazing!)

2) Add this middleware:

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

3) Make sure it goes after the VisitorTrackingMiddleware and you should find previous logins are automatically bumped when someone new logs in :)

莳間冲淡了誓言ζ 2024-07-25 08:04:21

如果您已经按照此处的建议使用 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()

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

这将建立一种“最后登录的用户获胜”系统。 如果您希望允许同一用户从同一 IP 多次登录,您可以将 .exclude() 添加到 Visitors 查找中。

If you're already using django-tracking as suggested here, there's a much easier way to implement this:

Define a signal handler:

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

Create a listener for the user_logged_in signal:

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

This will institute a sort of "last user to login wins" system. If you want to allow multiple logins by the same user from the same ip, you can add an .exclude() to the Visitors lookup.

神经大条 2024-07-25 08:04:21

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

您需要:

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

  2. 实现自定义身份验证后端 。 当触发并成功验证用户身份(只需调用 super)时,此后端将清除配置文件模型中用户的最后登录 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

Django's middleware will probably help you achieve this. The issue is that you will probably want to allow multiple anonymous sessions from the same IP address, even authenticated sessions for different users, but not authenticated sessions for the same user.

You'll want to:

  1. Create a user profile model to store the IP address of a user's last login. See Django's Storing additional information about users documentation.

  2. Implement a custom authentication backend. This backend, when triggered and successfully authenticating a user (just call super) would wipe out the user's last login IP in the profile model.

  3. Implement a subclass of Django's django.contrib.sessions.SessionMiddleware class. Implement process_request. If the request.user object's profile model has no IP address, set it and allow the request. If it has an IP, and the IP is different from the current request's IP (request.META.REMOTE_ADDR), then do whatever you like to either log out the other user, or return an error to the requestor.

  4. Update your settings.py file so that your custom auth backend is processed first, and so that your custom session middleware is also processed first. This involves updating settings.AUTHENTICATION_BACKENDS and settings.MIDDLEWARE_CLASSES.

三五鸿雁 2024-07-25 08:04:21

您需要使用自定义中间件来完成此操作。

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

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

现在您知道了 IP 地址,因此请检查您创建的模型(大致)会是什么样子像这样:

class SessionIPS(models.Model):
    session = models.ForeignKey(Session)
    IP = models.CharField(max_length=20)

因此,当创建或删除会话时,您将相应地修改会话 ip 表,并且当请求传入时,请确保该 IP 地址没有被其他会话使用。 如果是,则从中间件返回 Http404(或类似的内容)。

可以向您显示更多详细信息(甚至在其自己的模型中包含 IP 地址)的可插入应用程序是 django 跟踪

You'll need to do this with custom middleware.

In your middleware process_request() method you will have access to the request object so you can do something like the following:

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

Now you know the IP address, so check a model you create that (roughly) would look like this:

class SessionIPS(models.Model):
    session = models.ForeignKey(Session)
    IP = models.CharField(max_length=20)

So when a session is created or deleted you will modifiy your session ip's table accordingly, and when a request comes in make sure the IP address isn't being used for another session. If if is, then return a Http404 (or something like it) from the middleware.

A pluggable app that can show you a lot more detail (and even includes IP address in its own model) is django-tracking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文