Framework to be able to forcibly log users out of Django projects¶
This project provides the ability to log specific users out of your Django project.
Whilst you can easily log all users out by clearing your session table or similar blunt technique, due to the difficulty in enumerating specific user’s actual session entries from a user ID, logging-out troublemakers etc. is not really feasible “out of the box”.
You can iterate over all possible sessions and match them against a user, but with a heavy-traffic site with long-lasting sessions this can be prohibitively expensive.
Add django_force_logout.middleware.ForceLogoutMiddleware to MIDDLEWARE_CLASSES.
Configure FORCE_LOGOUT_CALLBACK in your settings to point to a method which, given a User instance, will return a nullable timestamp for that user. This would typically be stored on custom User, profile or some other field depending on your setup.
def force_logout_callback(user): return user.some_profile_model.force_logout FORCE_LOGOUT_CALLBACK = 'path.to.force_logout_callback'
Alternatively, you can just specify a lambda directly:
FORCE_LOGOUT_CALLBACK = lambda x: x.some_profile_model.force_logout
This callback is executed on every request by a logged-in user. Therefore, it is advisable that you have some sort of caching preventing additional database queries. Remember to ensure that you clear the cached value when wish to log a user out, otherwise you will have to wait for the cache entry to expire before the user will actually be logged out.
You are not restricted to returning a field from a SQL database (Redis may suit your needs better and avoid the caching requirement), but you must return a nullable timestamp.
To forcibly log that user out, simply set your timestamp field to the current time. For example:
user.some_profile_model.force_logout = datetime.datetime.utcnow() user.some_profile_model.save()
That’s it. The middleware will then log this user out on their next request.
A method which, when passed a User instance, will return a nullable timestamp for that user. See Installation for more details.
This project was inspired by a code snippet by Clement Nodet <http://clementnodet.com/>_.