Django – Session expiration renewal

Question:

I’m struggling with a question about sessions.

I wonder how to make a session expire if the user has not tried to connect to the website in a certain period of time (15 days for example).
In other words, I would like to renew the expiration date of a user session each time he/she is connecting to the site.

I scrapped a lot of websites but I couldn’t find any valuable example.

Asked By: m0numentum

||

Answers:

In your settings.py set SESSION_COOKIE_AGE

SESSION_COOKIE_AGE = 15 * 60 # 15 Minutes

Know more in the doc https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-SESSION_COOKIE_AGE

Answered By: Lemayzeur

One good solution, that I currently implement in one of my systems, if you would like your session to automatically renew on each request would be to write middleware that alters the expiration of the session to be extended in whichever views you need.

Note: this solution does make 2 DB queries for each request. 1 for the read and 1 for the update. This is a very small overhead (using debug toolbar at most the calls are usually only a few MS), but it is there.

For example:

from functools import wraps
from [project] import settings

class CookieMiddleware(object):
    """
    This middleware sets the login cookie to update timeout on every request
    """

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

    @staticmethod
    def process_view(request, view_func, args, kwargs):
        # ensure that we don't want to exclude this from running
        if getattr(view_func, 'cookie_not_important', False):
            print('cookie not important:', view_func.__name__)
            return None

        # the cookie is set, let's now set a new expire time to 30 minutes from now
        print('cookie expiry changed:', view_func.__name__)
        # it is probably smartest to grab this value back from settings
        expire_time = settings.SESSION_COOKIE_AGE
        # expire_time = 30 * 60
        request.session.set_expiry(expire_time)
        return view_func(request, *args, **kwargs)

    def __call__(self, request):
        response = self.get_response(request)
        return response


def cookie_not_important(view_func):
    """
    Decorator used to allow the exclusion of the cookie time being reset
    :param view_func: The view being wrapped
    :return:
    """

    def view_being_wrapped(*args, **kwargs):
        return view_func(*args, **kwargs)

    view_being_wrapped.cookie_not_important = True
    return wraps(view_func)(view_being_wrapped)

And now you can login and hit any view not wrapped by @cookie_not_important and the expiration time will reset based on the current value in settings.py

This is how the view would look wrapped though for completeness:

from django.urls import reverse

@cookie_not_important
def logout(request):
    del request.session
    return redirect(reverse('some_view_name'))
Answered By: ViaTech

This library could be helpful, it logs out inactive sessions after a given time https://github.com/yourlabs/django-session-security

Answered By: Duilio

If you set "True" to SESSION_SAVE_EVERY_REQUEST on "settings.py" as shown below, automatically, session is renewed(updated) every time the current page is reopened or other page is opened in Django Project.

SESSION_SAVE_EVERY_REQUEST = True # False by default

For example, session expires in 15 minutes. Then, from 3:00 pm, a session starts by logging in the page in Django Project so the session expires at 3:15 pm. Then, at 3:10 pm, the current page is reopened or other page is opened in Django Project so the session is renewed(updated) so the new session expires at 3:25 pm which means you are logged in until 3:25 pm.

Answered By: Kai – Kazuya Ito