How to force a user logout in Django?

前端 未结 10 2139
粉色の甜心
粉色の甜心 2020-11-30 17:27

In my Django app under certain conditions I want to be able to force users to log out by a username. Not necessarily the current user who is logged in, but another user. So,

相关标签:
10条回答
  • 2020-11-30 18:18

    I needed something similar in my app. In my case, if a user was set to inactive, I wanted to make sure if the user was already logged in that they will be logged out and not able to continue to use the site. After reading this post, I came to the following solution:

    from django.contrib.auth import logout
    
    class ActiveUserMiddleware(object):
        def process_request(self, request):
            if not request.user.is_authenticated:
                return
            if not request.user.is_active:
               logout(request)
    

    Just add this middleware in your settings and off you go. In the case of changing passwords, you could introduce a new field in the userprofile model that forces a user to logout, check for the value of the field instead of is_active above, and also unset the field when a user logs in. The latter can be done with Django's user_logged_in signal.

    0 讨论(0)
  • 2020-11-30 18:19

    As Tony Abou-Assaleh, I also needed to log out users who were set to inactive, so I started by implementing his solution. After some time I found out that the middleware is forcing a DB query on all requests (to check if the user was blocked), and thus hurts performance on pages that doesn't require login.

    I have a custom user object and Django >= 1.7, so what I ended up doing is overriding its get_session_auth_hash function to invalidate the session when the user is inactive. A possible implementation is:

    def get_session_auth_hash(self):
        if not self.is_active:
            return "inactive"
        return super(MyCustomUser, self).get_session_auth_hash()
    

    For this to work, django.contrib.auth.middleware.SessionAuthenticationMiddleware should be in settings.MIDDLEWARE_CLASSES

    0 讨论(0)
  • 2020-11-30 18:24

    This is in response to Balon's query:

    Yes, with around 140k sessions to iterate through I can see why Harold's answer may not be as fast as you may like!

    The way I would recommend is to add a model whose only two properties are foreign keys to User and Session objects. Then add some middleware that keeps this model up-to-date with current user sessions. I have used this sort of setup before; in my case, I borrowed the sessionprofile module from this Single Sign-On system for phpBB (see the source code in the "django/sessionprofile" folder) and this (I think) would suit your needs.

    What you would end up with is some management function somewhere in your code like this (assuming the same code names and layout as in the sessionprofile module linked above):

    from sessionprofile.models import SessionProfile
    from django.contrib.auth.models import User
    
    # Find all SessionProfile objects corresponding to a given username
    sessionProfiles = SessionProfile.objects.filter(user__username__exact='johndoe')
    
    # Delete all corresponding sessions
    [sp.session.delete() for sp in sessionProfiles]
    

    (I think this will also delete the SessionProfile objects, as from what I recall, Django's default behaviour when an object referenced by a ForeignKey is deleted is to cascade it and also delete the object containing the ForeignKey, but if not then it is trivial enough to delete the contents of sessionProfiles when you are done.)

    0 讨论(0)
  • 2020-11-30 18:24

    from django.contrib.sessions.models import Session

    deleting user session

    [s.delete() for s in Session.objects.all() if s.get_decoded().get('_auth_user_hash') == user.get_session_auth_hash()]
    
    0 讨论(0)
提交回复
热议问题