我希望防止同一个用户帐户在我的应用程序中有多个活动会话,并遵循this question的回答。
我在我的models.py中实现了这一点
from django.conf import settings
from django.db import models
from django.contrib.sessions.models import Session
class UserSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
session = models.OneToOneField(Session, on_delete=models.CASCADE)
from django.contrib.auth import user_logged_in
from django.dispatch.dispatcher import receiver
@receiver(user_logged_in)
def remove_other_sessions(sender, user, request, **kwargs):
# remove other sessions
Session.objects.filter(usersession__user=user).delete()
# save current session
request.session.save()
# 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)
)不过,我注意到了一种奇怪的行为。
如果我用一个帐户登录,然后打开一个匿名窗口并使用相同的凭据登录,则第一个帐户将被注销(这正是我想要的)。
但是,如果我用一个帐户登录,然后关闭浏览器,下次我要登录时,我会在行中得到一个错误:
# save current session
request.session.save()使用以下跟踪(没有太多信息.):
UpdateError at / 没有提供异常消息
控制台日志显示错误来自
django.contrib.sessions.backends.base.UpdateError在此之后,如果刷新页面,则可以成功登录。
对可能发生的事有什么见解吗?
发布于 2019-03-08 13:43:13
您正在接收该错误,因为数据库中不再有要更新的会话,您已经删除了所有活动会话(在此之上2行)。要解决这个问题,只需在清除当前活动会话时忽略它们:
@receiver(user_logged_in)
def remove_other_sessions(sender, user, request, **kwargs):
# remove other sessions
old_sessions = Session.objects.filter(usersession__user=user)
if request.session.session_key:
old_sessions = old_sessions.exclude(session_key=request.session.session_key)
old_sessions.delete()
# save current session
request.session.save()
# 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)
)发布于 2020-02-12 09:25:29
GwynBleidD的回答很好!但这里有个小虫子:
if request.session.session_key:
old_sessions = old_sessions.exclude(session_key=request.session.session_key)
应写为:
if request.session.session_key:
old_sessions = old_sessions.exclude(session_key=request.session.session_key).delete()
else:
old_sessions.delete()否则,当您第二次尝试在同一台计算机上登录时,将出现错误。
https://stackoverflow.com/questions/55063904
复制相似问题