1

I am using Django 1.10 with Django-REST.

I need to know if a user is logged in or not (offline / online) How can I do that? I am using token based authentication.

I tried this article but it didn't work for my use case... it seems to be too old

Mor Paz
  • 2,088
  • 2
  • 20
  • 38
Oz Bar-Shalom
  • 1,747
  • 1
  • 18
  • 33
  • look at this post, maybe its helps you http://stackoverflow.com/questions/29663777/how-to-check-whether-a-user-is-online-in-django-template – Zagorodniy Olexiy Dec 17 '16 at 15:43

2 Answers2

3

Ok, After trying a few different things I got it. Here's how I made it work:

First create a Middleware to store on memcache the last time the user has accessed the server.

import datetime
from django.core.cache import cache
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin


class ActiveUserMiddleware(MiddlewareMixin):

    def process_request(self, request):
        current_user = request.user
        if request.user.is_authenticated():
            now = datetime.datetime.now()
            cache.set('seen_%s' % (current_user.username), now,
                           settings.USER_LASTSEEN_TIMEOUT)

Then extend the User serializer with the properties online and last_seen

class UserSerializer(serializers.ModelSerializer):

    last_seen = serializers.SerializerMethodField()
    online = serializers.SerializerMethodField()

    class Meta:
        model = User
        fields = ('url', 'id', 'username', 'email', 'first_name', 'last_name', 'groups', 'is_staff', 'avatar', 'last_seen', 'online')

    def get_last_seen(self, obj):
        last_seen = cache.get('seen_%s' % obj.username)
        obj.last_seen = last_seen
        return last_seen

    def get_online(self, obj):
        if obj.last_seen:
            now = datetime.datetime.now()
            delta = datetime.timedelta(seconds=settings.USER_ONLINE_TIMEOUT)
            if now > obj.last_seen + delta:
                return False
            else:
                return True
        else:
            return False

Settings.py need to have this new settings:

if os.name == 'nt':
    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
            'LOCATION': 'c:/foo/bar',
        }
    }
else:
    CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
                'LOCATION': '127.0.0.1:11211',
            }
    }


# Number of seconds of inactivity before a user is marked offline
USER_ONLINE_TIMEOUT = 300

# Number of seconds that we will keep track of inactive users before
# their last seen is removed from the cache
USER_LASTSEEN_TIMEOUT = 60 * 60 * 24 * 7

and do not forget to add your middleware:

'api.resources.users.middleware.active_user.ActiveUserMiddleware',
Mor Paz
  • 2,088
  • 2
  • 20
  • 38
Oz Bar-Shalom
  • 1,747
  • 1
  • 18
  • 33
-2

Write a piece of Javascript which will send a dummy request to server. Put this to repeat on say 60 or some seconds. As long as you are receiving requests you know page is on. Then you can check if that user is authenticated.

Shiv
  • 1,912
  • 1
  • 15
  • 21
  • Users always requests the server.. I think I need a middleware to store last access. And when getting user info I will be able to detect if he is logged in recently...But I don`t know how to do that – Oz Bar-Shalom Dec 17 '16 at 15:42
  • There can be many solutions to this problem. I proposed a solution which will solve the problem even if user is idle. You do not like it downvote it. – Shiv Dec 17 '16 at 15:43