【问题标题】:Django - Only allow one session per user results in Bad requestDjango - 每个用户只允许一个会话导致错误请求
【发布时间】:2021-02-02 04:14:08
【问题描述】:

如果我在刷新第一个浏览器时登录另一个浏览器,出于某种原因,我会返回 http 400(错误请求)。我只想实现一个用户一次只能有一个活动会话。

models.py

class UserSession(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    session = models.OneToOneField(Session, on_delete=models.CASCADE)

信号.py

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

出于某种原因,第一个浏览器不会删除会话,而是保留会话,我会返回 http 400,直到我手动删除会话密钥。 我希望如果会话密钥不再存在,用户将被重定向到登录。能帮忙?

亲切的问候

【问题讨论】:

    标签: django session signals


    【解决方案1】:

    不要删除旧会话,而是将它们的expire_date 设置为当前时间。这样,当使用旧会话密钥时,会话中间件将处理旧会话的删除,因为它将“过期”

    @receiver(user_logged_in)
    def remove_other_sessions(sender, user, request, **kwargs):
        # Force other sessions to expire
        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.update(expire_date=datetime.datetime.now())
    
        # 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)
        )
    

    【讨论】:

    • 必须验证这一点,谢谢。将尽快将您的回答标记为解决方案
    • 我尝试了您的解决方案,但如果会话设置为过期,则不会发生任何事情。换句话说,我可以同时为一个用户进行 X 会话
    • 我已经尝试了该解决方案,并且它按预期工作。另一个会话是在完全不同的浏览器或隐身标签中吗?
    猜你喜欢
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 2014-10-11
    • 2015-03-12
    • 2019-10-12
    • 2015-11-03
    • 1970-01-01
    • 2013-11-10
    相关资源
    最近更新 更多