How to log a user out in django (without the request)

Viewed 2736

In django I can log a user out with:

from django.contrib.auth import logout
logout(request)

However, how would I manually log a use out -- for example I want to "sign users out of all tabs" -- that is, how do I flush all session for that user in my db?

3 Answers

You can add the following method to your user object:

from django.utils import timezone
from django.contrib.sessions.models import Session

class User(models.model):
    ...

    def remove_all_sessions(self):
        user_sessions = []
        all_sessions  = Session.objects.filter(expire_date__gte=timezone.now())
        for session in Session.objects.all():
            if str(self.pk) == session.get_decoded().get('_auth_user_id'):
                user_sessions.append(session.pk)
        return Session.objects.filter(pk__in=user_sessions).delete()

You can iterate over all sessions in DB, decode all of them, and delete those belonging to that user. But it's slow, particularly if your site has high traffic and there are lots of sessions.

If you need a faster solution, you can use a session backend that lets you query and get the sessions of a specific user. In these session backends, Session has a foreign key to User, so you don't need to iterate over all session objects:

Using these backends, deleting all sessions of a user can be done in a single line of code:

user.session_set.all().delete()

Disclaimer: I am the author of django-qsessions.

To understand this problem, consider what happens with the database backend. When a user logs in, Django adds a row to the django_session database table. Django updates this row each time the session data changes. If the user logs out manually, Django deletes the row. But if the user does not log out, the row never gets deleted. A similar process happens with the file backend.

Django does not provide automatic purging of expired sessions. Therefore, it’s your job to purge expired sessions on a regular basis. Django provides a clean-up management command for this purpose: clearsessions. It’s recommended to call this command on a regular basis, for example as a daily cron job.

Note that the cache backend isn’t vulnerable to this problem, because caches automatically delete stale data. Neither is the cookie backed, because the session data is stored by the users’ browsers.

so run:

$ ./manage.py clearsessions
Related