在Django应用中,每个用户只允许同时登录一个账号

3

在Django应用程序中,是否可以允许每个用户只有一个并发登录?如果可以,你该如何处理?

4个回答

8

我在我的应用程序中需要这个功能,因此我创建了一个django软件包,现在已经发布到pypi(pip install django-preventconcurrentlogins)。

该软件包基于peterdemin的代码片段:https://gist.github.com/peterdemin/5829440

希望这对未来有所帮助。


太棒了,谢谢!它不再与最新的Django版本兼容,pull request已在此处提交。 - Christof

6

这个问题在stackoverflow.com上已经得到了解答,可以点击这里查看。


链接的stackoverflow答案有额外的要求,即仅防止来自不同IP的登录,这不适用于此问题。更好的链接问题是https://dev59.com/CF7Va4cB1Zd3GeqPFwZa。 - tobltobs

4
你需要创建一些模型,为每个用户保存session_key,并创建中间件来检查该模型中每个用户的session_key是否等于request.session_key,如果不相等,则删除该会话(=注销用户,只允许当前用户保留)。
#models.py
class Visitor(model.model):
    user = models.OneToOneField(User)
    session_key = models.CharField(null=True, blank=True)

#and you need to setup signal catching from User model - so for each User Visitor is created

#middleware.py
class OnlyOneUserMiddleware(object):
    def process_request(self, request):
         cur_session_key = request.user.visitor.session_key
         if cur_session_key and cur_session_key != request.session.session_key:
             Session.objects.get(session_key=cur_session_key).delete()
         #the following can be optimized(do not save each time if value not changed)
         request.user.visitor.session_key = request.session.session_key
         request.user.visitor.save()

1
干得好,看看我基于你的片段制作的gist:https://gist.github.com/peterdemin/5829440我的实现不使用信号。 - peterdemin
现在有一个适用于PiP的Django模块 https://github.com/pcraston/django-preventconcurrentlogins - creyD

0

我假设你的意思是同时登录,而不是同一时间只有一个“登录”。

我以前从未编写过Django应用程序。但我在其他语言中使用的一种方法是,在数据库中存储已登录用户的会话ID。

例如,如果您的数据库中有一个用户表,请添加一个名为“session_id”的字段,然后在用户登录时将其设置为其当前会话ID。在每个页面加载时检查他们当前的会话是否与用户表中的session_id匹配。请记住,每当您在应用程序中重新生成他们的session_id时,都需要更新数据库,以便他们不会被注销。

有些人在用户登录时,只是将所有用户详细信息存储到会话中,并且在新页面加载时不再调用数据库。因此,对于某些人来说,这个“额外”的SQL查询可能看起来是错误的。对于我来说,我总是在每个页面加载时进行新的查询,以重新验证用户并确保他们的帐户未被删除/暂停,并确保他们的用户名/密码组合仍然相同。(如果其他地方的某个人更改了密码或管理员怎么办?)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接