How to expire Django session in 5minutes?

DjangoSession

Django Problem Overview


I am using this to login the user in:

def login_backend(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user)
            request.session.set_expiry(300)
            return HttpResponseRedirect('/overview/')
        else:
            return HttpResponseRedirect('/login_backend/')
    else:
        return render_to_response('login_backend.html', context_instance=RequestContext(request))

I want session to expire after 5mins thus I added request.session.set_expiry(300) in the view above. But the session is never expiring. What am I doing wrong?

Django Solutions


Solution 1 - Django

There are two parameters to expire sessions, SESSION_EXPIRE_AT_BROWSER_CLOSE and SESSION_COOKIE_AGE. If you want to expire in 5 minutes yours settings should like as:

SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_COOKIE_AGE = 5 * 60 #

To combine both learn how do it writing your custom middleware "Is there a way to combine behavior of SESSION_EXPIRE_AT_BROWSER_CLOSE and SESSION_COOKIE_AGE"

Solution 2 - Django

Update for Django 1.6

The middleware code below is not working in Django 1.6 and above version because of json serializable. To make it work in all versions of Django, put the session serializer.

settings.py

#Handle session is not Json Serializable
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'

The above sample of serializer is for Django 1.6. Kindly search for other version. Thanks...

Create middleware.py

from datetime import datetime, timedelta
from django.conf import settings
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()

Update your settings.py:

MIDDLEWARE_CLASSES = [
    .........................

    'app_name.middleware.AutoLogout', 
]

# Auto logout delay in minutes
AUTO_LOGOUT_DELAY = 5 #equivalent to 5 minutes

Solution 3 - Django

Django 1.9

Edit your settings.py and add the following:

# SESSION AGE 5 Minutes
SESSION_COOKIE_AGE = 5*60

Solution 4 - Django

Depending on your project, this might not be sufficient.

For example, what if the user spends 6 minutes filling a form and clicks "Save" ? Browser will be redirected to the login page and form data will be lost.

Also, there is a potential security issue if the user leaves his workstation with confidential data in an opened page of the browser.

Also, what if the user reads a page during 6 minutes ? It is then not really cool to log him out without warning or any way to extend his session ...

Considering these matters, you might find django-session-security useful.

Solution 5 - Django

I use Django 2.1.7 and the easiest way to expire django session is:

  • first you need to install django-session-timeout with command:

    pip install django-session-timeout

  • then you need to update your SessionTimeoutMiddleware in settings.py

    MIDDLEWARE_CLASSES = [
         ...
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django_session_timeout.middleware.SessionTimeoutMiddleware',
         ...
    ]
    
  • at last you need to add SESSION_EXPIRE_SECONDS at the end of settings.py:

    SESSION_EXPIRE_SECONDS = 300 # 300 seconds = 5 minutes

By default, the session will expire X seconds after the start of the session. To expire the session X seconds after the last activity, use the following setting:

SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True

Solution 6 - Django

Set session time needed before calling login()!

...
request.session.set_expiry(300)
login(request, user)
...     

   

Solution 7 - Django

This works for me #settings.py

TIME= 240*60  //four hours  or your time
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
SESSION_EXPIRE_AT_BROWSER_CLOSE= True
SESSION_COOKIE_AGE = TIME    //change expired session
SESSION_IDLE_TIMEOUT = TIME  //logout

#middleware.py

from django.contrib.auth import logout
from django.contrib import messages
import datetime
from django.shortcuts import redirect

import settings

class SessionIdleTimeout:
    def process_request(self, request):
        if request.user.is_authenticated():
            current_datetime = datetime.datetime.now()
            if ('last_login' in request.session):
                last = (current_datetime - request.session['last_login']).seconds
                if last > settings.SESSION_IDLE_TIMEOUT:
                    logout(request, login.html)
            else:
                request.session['last_login'] = current_datetime
        return None

Solution 8 - Django

To bring @jhonnylopez's answer up to date and to log out after a period of inactivity, rather than after a given time:

settings.py

# Logout after a period of inactivity
INACTIVE_TIME = 15*60  # 15 minutes - or whatever period you think appropriate
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
SESSION_EXPIRE_AT_BROWSER_CLOSE= True
SESSION_COOKIE_AGE = INACTIVE_TIME   # change expired session
SESSION_IDLE_TIMEOUT = INACTIVE_TIME  # logout

middleware.py

from django.contrib.auth import logout
import datetime

from settings import SESSION_IDLE_TIMEOUT


class SessionIdleTimeout(object):
    """Middle ware to ensure user gets logged out after defined period if inactvity."""
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.user.is_authenticated:
            current_datetime = datetime.datetime.now()
            if 'last_active_time' in request.session:
                idle_period = (current_datetime - request.session['last_active_time']).seconds
                if idle_period > SESSION_IDLE_TIMEOUT:
                    logout(request, 'login.html')
            request.session['last_active_time'] = current_datetime

        response = self.get_response(request)
        return response

Solution 9 - Django

If you are looking for simple expiry after 5 minutes and do not care about prompting the user or allowing them to extend the session, django-session-timeout works well.

pip install django-session-timeout
SESSION_EXPIRE_SECONDS = 300  # 5 min
SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True
SESSION_TIMEOUT_REDIRECT = '/accounts/logout/'  # redirect to whatever page

While this is a quick fix for session expiry after 5 min, with redirect to a specified page (logout), it does not help with some of the other issues addressed in this post around warning the user or giving the opportunity to extend a session. With the last activity setting set to True, it will continue to extend the session based on activity, however if they are reading a page or filling out a form that takes longer than 5 minutes, it will log them out, possibly causing issues for your users depending on your site functionality.

Further documentation here: https://pypi.org/project/django-session-timeout/

I have not implemented it yet, but plan to next. Some other posts have recommended django-session-security if you need added functionality of prompting the user and allowing them the option to extend the session.

These are good alternatives to not adding your own middleware, if that is not the route you want to go.

Solution 10 - Django

Session needs to be set before calling login() as pointed out by Dmitry Nikitin. Also you need to add SESSION_SAVE_EVERY_REQUEST = True in the settings file. This settings will keep updating the expiry time with every request. So after 5 minutes of inactivity, session will expire.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpynoviceView Question on Stackoverflow
Solution 1 - Djangodani herreraView Answer on Stackoverflow
Solution 2 - DjangocatherineView Answer on Stackoverflow
Solution 3 - DjangoSlipstreamView Answer on Stackoverflow
Solution 4 - DjangojpicView Answer on Stackoverflow
Solution 5 - DjangoMihael WaschlView Answer on Stackoverflow
Solution 6 - DjangoDmitry NikitinView Answer on Stackoverflow
Solution 7 - Djangojhonny lopezView Answer on Stackoverflow
Solution 8 - DjangoPsionmanView Answer on Stackoverflow
Solution 9 - DjangoJSSView Answer on Stackoverflow
Solution 10 - DjangoWhite CastleView Answer on Stackoverflow