Django - detect if user is online / offline

2019-02-11 09:04发布

问题:

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

回答1:

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',


回答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.