Most optimized way to delete all sessions for a specific user in Django?

后端 未结 5 1320
感动是毒
感动是毒 2021-02-01 18:40

I\'m running Django 1.3, using Sessions Middleware and Auth Middleware:

# settings.py

SESSION_ENGINE = django.contrib.sessions.backends.db   # Persist sessions          


        
相关标签:
5条回答
  • 2021-02-01 18:56

    This is not a direct answer, but it solves your problem and reduces DB hits to zero. With recent versions of Django you can use the cookie based session backend:

    https://docs.djangoproject.com/en/dev/topics/http/sessions/#cookie-session-backend

    0 讨论(0)
  • 2021-02-01 18:57

    Another version of a function using list comprehension that will just straight up delete every unexpired session of a user:

    from django.utils import timezone
    from django.contrib.sessions.models import Session
    
    
    def delete_all_unexpired_sessions_for_user(user):
        unexpired_sessions = Session.objects.filter(expire_date__gte=timezone.now())
        [
            session.delete() for session in unexpired_sessions
            if str(user.pk) == session.get_decoded().get('_auth_user_id')
        ]
    
    0 讨论(0)
  • 2021-02-01 19:02

    If you return a QuerySet from your all_unexpired_sessions_for_user function, you could limit your database hits to two:

    def all_unexpired_sessions_for_user(user):
        user_sessions = []
        all_sessions  = Session.objects.filter(expire_date__gte=datetime.datetime.now())
        for session in all_sessions:
            session_data = session.get_decoded()
            if user.pk == session_data.get('_auth_user_id'):
                user_sessions.append(session.pk)
        return Session.objects.filter(pk__in=user_sessions)
    
    def delete_all_unexpired_sessions_for_user(user, session_to_omit=None):
        session_list = all_unexpired_sessions_for_user(user)
        if session_to_omit is not None:
            session_list.exclude(session_key=session_to_omit.session_key)
        session_list.delete()
    

    This gives you a total of two hits to the database. Once to loop over all of the Session objects, and once to delete all of the sessions. Unfortunately, I don't know of a more direct way to filter through the sessions themselves.

    0 讨论(0)
  • 2021-02-01 19:05

    It might be helpful to use:

    • django-password-session in order to invalidate user's sessions after a password is changed. Since Django 1.7 this feature implemented out of the box.
    • django-admin clearsessions to remove expired cookies
    0 讨论(0)
  • 2021-02-01 19:19

    The most efficient way is to store the session id of the user during login. You can access the session ID using request.session._session_key and store it in a separate model which has reference to the user. Now when you want to remove all the sessions of the user, just query this model which will return all the active sessions for the user in question. Now you need to delete only these sessions from the session table. Much better than having to look up all the sessions to filter out just sessions for a particular user.

    0 讨论(0)
提交回复
热议问题