Is there a way to combine behavior of SESSION_EXPIRE_AT_BROWSER_CLOSE and SESSION_COOKIE_AGE

核能气质少年 提交于 2019-11-28 05:08:33
dani herrera

As you explains, SESSION_EXPIRE_AT_BROWSER_CLOSE and SESSION_COOKIE_AGE are not compatible. When you set an expiration date to a cookie, this cookie becomes no browser-length cookie.

Then, in order to achieve your desired behavior, you should set SESSION_EXPIRE_AT_BROWSER_CLOSE as True and control expire timeout by hand.

An elegant way to control by hand expire timeout is:

  1. Create a new custom middleware that control timeout.
  2. Modify settings.py to enable your custom middleware (and sessions).

The timeout custom middleware can looks like:

# updated version that should work with django 1.10 middleware style
# tested up to django 2.2

import time
from django.conf import settings


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

    def __call__(self, request):
        if request.user.is_authenticated:
            if 'last_request' in request.session:
                elapsed = time.time() - request.session['last_request']
                if elapsed > settings.SESSION_IDLE_TIMEOUT:
                    del request.session['last_request'] 
                    logout(request)
                    # flushing the complete session is an option as well!
                    # request.session.flush()  
            request.session['last_request'] = time.time()
        else:
            if 'last_request' in request.session:
                del request.session['last_request']

        response = self.get_response(request)

        return response

Solution for ancient Django versions (pre 1.10)

class timeOutMiddleware(object):

    def process_request(self, request):
        if request.user.is_authenticated():
            if 'lastRequest' in request.session:            
                elapsedTime = datetime.datetime.now() - \
                              request.session['lastRequest']
                if elapsedTime.seconds > 15*60:
                    del request.session['lastRequest'] 
                    logout(request)

            request.session['lastRequest'] = datetime.datetime.now()
        else:
            if 'lastRequest' in request.session:
                del request.session['lastRequest'] 

        return None

Remember enable sessions in order to store lastRequest.

This solution is wrote and tested be me and is now working in my site. This code has GNU license ;)

New on django 1.6 ( ... two years later ... )

Datetime and timedelta values are only serializable if you are using the PickleSerializer. If not, perhaps easy solution is translate datetime to unix timestamp and back. Be free to post below this translation.

Edited

django-session-security app provides a mechanism to logout inactive authenticated users. Take a look.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!