首页 > 解决方案 > 如何使 django 用户处于非活动状态并使其所有会话无效

问题描述

为了使用户处于非活动状态,我通常会这样做:

User.objects.get(pk=X).update(is_active=False)

但是,这不会注销用户或执行任何与会话相关的操作。django 中是否有内置功能可以使用户立即处于非活动状态,或者实现此目的的最佳方法是什么?

一个类似的答案是:https ://stackoverflow.com/a/954318/651174 ,但如果有数百万个会话(这是一种遍历所有会话的蛮力方式),那效果就不太好了。虽然这是从 2009 年开始的,但希望今天有更好的方法。

标签: djangodjango-sessions

解决方案


如前所述,您可以使用django-user-sessiondjango-qsessions。但这些包括一些其他元数据,例如用户代理和 IP 地址,您可能出于某种原因不需要这些。然后您需要编写自定义会话后端

我稍微调整了示例并根据我的需要创建了一个。

session_backend.py:

from django.contrib.auth import get_user_model
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.contrib.sessions.base_session import AbstractBaseSession
from django.db import models

User = get_user_model()


class QuickSession(AbstractBaseSession):
    # Custom session model which stores user foreignkey to asssociate sessions with particular users.
    user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)

    @classmethod
    def get_session_store_class(cls):
        return SessionStore


class SessionStore(DBStore):
    @classmethod
    def get_model_class(cls):
        return QuickSession

    def create_model_instance(self, data):
        obj = super().create_model_instance(data)

        try:
            user_id = int(data.get('_auth_user_id'))
            user = User.objects.get(pk=user_id)
        except (ValueError, TypeError, User.DoesNotExist):
            user = None
        obj.user = user
        return obj

在 settings.py 中:

SESSION_ENGINE = 'path.to.session_backend'

删除用户的所有会话:

from session_backend import QuickSession
QuickSession.objects.filter(user=request.user).delete()

如果 is_active 字段设置为 False,您可以为用户模型编写自定义保存方法以自动删除用户的所有会话。

请记住,未登录用户的用户字段将为 NULL。


推荐阅读