为了账号安全,请及时绑定邮箱和手机立即绑定

Django - 会话管理

Django - 会话管理

慕村225694 2021-11-30 15:56:38
我想防止同一个用户帐户在我的应用程序中具有多个活动会话,并遵循此问题的答案。我将其实现到我的models.py:from django.conf import settingsfrom django.db import modelsfrom django.contrib.sessions.models import Sessionclass 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_infrom 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 sessionrequest.session.save()具有以下追溯(没有太多信息..):更新错误在 /未提供异常消息控制台日志显示错误来自django.contrib.sessions.backends.base.UpdateError在此之后,如果我刷新页面,则可以成功登录。对可能发生的事情的任何见解?
查看完整描述

2 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

您收到该错误是因为数据库中不再有要更新的会话,您已经删除了其上方 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)

    )


查看完整回答
反对 回复 2021-11-30
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

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


否则当您第二次尝试在同一台计算机上登录时会出现错误。


查看完整回答
反对 回复 2021-11-30
  • 2 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信