Autologout a user after specific time in django
Asked Answered
R

2

6

I need to logout a user after some specific time(lets take it as 1 min for now), and so created a middleware class as below

myproject/middleware.py

from datetime import datetime, timedelta
from django.contrib import auth


class AutoLogout:
  def process_request(self, request):
    if not request.user.is_authenticated() :
      #Can't log out if not logged in
      return

    try:
      if datetime.now() - request.session['last_touch'] > timedelta( 0, settings.AUTO_LOGOUT_DELAY * 60, 0):
        auth.logout(request)
        del request.session['last_touch']
        return
    except KeyError:
      pass

    request.session['last_touch'] = datetime.now()

settings.py

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'myproject.middleware.HttpErrorHandler',
    'myproject.middleware.AutoLogout'
)
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
AUTO_LOGOUT_DELAY = 1

Djagno version was 1.4.12

But the above code was not working and i am not sure where i was doing wrong, so can someone let me know why the above code was not working and how to logout a user for every 1 min or 5 min ?

Rockel answered 28/7, 2015 at 7:42 Comment(5)
Are you getting any exception in 'try' block ?Daisey
Can you put in some logging to see whether you get to the try, inside the if, etc.Spit
actually it was not entering in to process_request method it seems, because i have used some print statements but couldn't able to see then on terminal outputRockel
@DanielRoseman It was not even entering in to process_request methodRockel
maybe you should use jquery ajax which will send GET or POST request which will run some view in specific time, which will logout user..Ewaewald
E
12

From Django 1.7 Session management was introduced. Under settings there are two parameters that you can add to help you allow auto logout without necessarily writing you own middleware.

  1. SESSION_EXPIRE_AT_BROWSER_CLOSE
  2. SESSION_COOKIE_AGE

Hope that answers your query. Happy coding!!

Eunaeunice answered 9/3, 2016 at 6:44 Comment(0)
B
1

These answers are all good, but a little out of date and slightly incomplete as of 2023 and Django 4.2, so I've provided some clarifications and colour below for two different common use-cases:

  1. Auto log-out after X amount of time since log-in
  2. Auto log-out after X amount of time of inactivity

Use-Case 1: To log-out users automatically after 'X' amount of time has elapsed since they last logged-in

SIMPLE APPROACH (appropriate for most projects):

Inside settings.py, set SESSION_COOKIE_AGE = X, where 'X' is the amount of time to elapse since last log-in in terms of seconds, and SESSION_SAVE_EVERY_REQUEST = False.

For example, the below code in settings.py will log users out after 5 days have elapsed since their last log-in:

SESSION_COOKIE_AGE = 5 * 24 * 60 * 60  # 5 days
SESSION_SAVE_EVERY_REQUEST = False  # Only save session when session modified
  • CAVEAT: This simplified approach will work provided your views and middleware other than log-in/log-out do not modify the request.session object. This approach will fail in its aim if you modify the session object, as doing so will update and reset the session cookie's age.

COMPLEX APPROACH (appropriate for projects that modify sessions in non-auth views, or which have bespoke requirements):

If your views or middleware do change the session object, or if you want fine-grained control over this (e.g. different settings for different users), you will need to use custom middleware.

The below code is not thoroughly tested, and is dependent on your user model implementing a last_login field (Django includes this by default for User, AbstractUser and AbstractBaseUser). But as an example your middleware should look something like this inside myapp/middleware.py:

class AutoLogoutMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.user.is_authenticated:
            if timezone.now() - request.user.last_login > timedelta(days=5):
                logout(request)  # Logout if 5 or more days since last login
        response = self.get_response(request)
        return response

And you would then import your middleware into settings.py as below (ensuring it comes AFTER sessions and auth middleware):

MIDDLEWARE = [
    # ... possibly earlier middleware ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # ... possibly other middleware ...
    'myapp.middleware.AutoLogoutMiddleware',
    # ... possibly further middleware ...
]

Use-Case 2: To log-out users automatically after 'X' amount of time has elapsed since they were last active

This can be achieved easily as follows:

Inside settings.py, set SESSION_COOKIE_AGE = X, where 'X' is the amount of time to elapse since last activity in terms of seconds, and SESSION_SAVE_EVERY_REQUEST = True.

For example, the below code in settings.py will log users out after 30 minutes of inactivity.

SESSION_COOKIE_AGE = 30 * 60  # 30 minutes
SESSION_SAVE_EVERY_REQUEST = True  # Refresh session whenever user is active

Note you can also achieve a similar effect with custom middleware, if you have more bespoke requirements, but this may be more complex than needed.

  • CAVEAT 1: Note that setting SESSION_SAVE_EVERY_REQUEST = True will increase the number of hits to your database by 1 for each request, as each request will now be updating the session. Ensure you can cope with this additional database load.

  • CAVEAT 2: Be very careful about setting too low a value for SESSION_COOKIE_AGE, e.g. in a situation where you have a large form. If the user takes longer than 'X' amount of time filling in your form, then on submit they will be logged out and redirected to the log-in page, and all their form data will be lost (potentially very bad UX, typical of many a poorly designed site).


P.S. the inclusion of SESSION_EXPIRE_AT_BROWSER_CLOSE is also a powerful session-based security measure for many use-cases. All Django session settings can be seen in the official docs here.

Bondstone answered 29/11, 2023 at 12:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.