# -*- coding: utf-8 -* from django.conf import settings from django.core.cache import cache, get_cache from django.utils.importlib import import_module class UserRestrictMiddleware(object): def process_request(self, request): """ Checks if different session exists for user and deletes it. """ if request.user.is_authenticated(): cache = get_cache('default') cache_timeout = 86400 cache_key = "user_pk_%s_restrict" % request.user.pk cache_value = cache.get(cache_key) if cache_value is not None: if request.session.session_key != cache_value: engine = import_module(settings.SESSION_ENGINE) session = engine.SessionStore(session_key=cache_value) session.delete() cache.set(cache_key, request.session.session_key, cache_timeout) else: cache.set(cache_key, request.session.session_key, cache_timeout) # vim: ai ts=4 sts=4 et sw=4Hope you like it.
Remember, to put UserRestrictMiddleware somewhere after Session Middleware in MIDDLEWARE_CLASSES (settings.py)
4 comments:
If user A accesses the site and then user B comes along with the same credentials (but a different session), then presumably session.delete() will mean that user A is logged out?
Presumably you could replace session.delete() with request.session.delete() to achieve the effect of B being logged out while A remains logged in?
(Apologies, I only dabble in Django... I was trying to work out whether there is a race condition in the code.)
Thanks for your comment.
If I did this the way you wrote (User B can't log in until user A logs out) than User A would lock himself out and would not be able to log in from another place (initiating new session).That's not what I meant to achieve.
The design was to disable users multi login in one of paid services I manage. If user A provides his user password to another person than he will be locked out each time this person logs in (and vice-versa).
This is how I understood your post.
Let me know if you see this the other way.
My script is not perfect. It presumes that between the time of logging in both User A and User B cache was not cleared.
It could be done with an additional last_session = models.CharField() key attached to UserProfile (or new User model Django >= 1.5) but it would hit the database each time.
I am using redis instance for this "caching" which is not cleared often.
Thanks
This Middleware also prevents multiple login in same browser? I mean multiple tabs of the same web service.
If not, how i can do that?
@Jota
Why would you like to prevent using multiple tabs from the same web browser ?
Multiple tabs share the same session, so it will (blocking) work only if you open a new "private/incognito mode" tab as it doesn't share the same session.
Also my solution prevents from using the same account on 2 different browsers on the same computer.
Post a Comment