55👍
I am just pretty new to use Django.
I wanted to make session expire if logged user close browser or are in idle(inactivity timeout) for some amount of time. When I googled it to figure out, this SOF question came up first. Thanks to nice answer, I looked up resources to understand how middlewares works during request/response cycle in Django. It was very helpful.
I was about to apply custom middleware into my code following top answer in here. But I was still little bit suspicious because best answer in here was edited in 2011. I took more time to search little bit from recent search result and came up with simple way.
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
SESSION_COOKIE_AGE = 10 # set just 10 seconds to test
SESSION_SAVE_EVERY_REQUEST = True
I didn’t check other browsers but chrome.
- A session expired when I closed a browser even if SESSION_COOKIE_AGE set.
- Only when I was idle for more than 10 seconds, A session expired. Thanks to SESSION_SAVE_EVERY_REQUEST, whenever you occur new request, It saves the session and updates timeout to expire
To change this default behavior, set the SESSION_SAVE_EVERY_REQUEST setting to True. When set to True, Django will save the session to the database on every single request.
Note that the session cookie is only sent when a session has been created or modified. If SESSION_SAVE_EVERY_REQUEST is True, the session cookie will be sent on every request.
Similarly, the expires part of a session cookie is updated each time the session cookie is sent.
I just leave answer so that some people who is a kind of new in Django like me don’t spend much time to find out solution as a way I did.
49👍
Here’s an idea… Expire the session on browser close with the SESSION_EXPIRE_AT_BROWSER_CLOSE
setting. Then set a timestamp in the session on every request like so.
request.session['last_activity'] = datetime.now()
and add a middleware to detect if the session is expired. something like this should handle the whole process…
from datetime import datetime
from django.http import HttpResponseRedirect
class SessionExpiredMiddleware:
def process_request(request):
last_activity = request.session['last_activity']
now = datetime.now()
if (now - last_activity).minutes > 10:
# Do logout / expire session
# and then...
return HttpResponseRedirect("LOGIN_PAGE_URL")
if not request.is_ajax():
# don't set this for ajax requests or else your
# expired session checks will keep the session from
# expiring :)
request.session['last_activity'] = now
Then you just have to make some urls and views to return relevant data to the ajax calls regarding the session expiry.
when the user opts to “renew” the session, so to speak, all you have to do is set requeset.session['last_activity']
to the current time again
Obviously this code is only a start… but it should get you on the right path
- [Django]-Django: using more than one database with inspectdb?
- [Django]-Django – Clean permission table
- [Django]-How to query Case-insensitive data in Django ORM?
28👍
django-session-security does just that…
… with an additional requirement: if the server doesn’t respond or an attacker disconnected the internet connection: it should expire anyway.
Disclamer: I maintain this app. But I’ve been watching this thread for a very, very long time 🙂
- [Django]-Django error: got multiple values for keyword argument
- [Django]-Django rest framework, use different serializers in the same ModelViewSet
- [Django]-How to set environment variables in PyCharm?
16👍
One easy way to satisfy your second requirement would be to set SESSION_COOKIE_AGE value in settings.py to a suitable amount of seconds. For instance:
SESSION_COOKIE_AGE = 600 #10 minutes.
However, by only doing this the session will expire after 10 minutes whether or not the user exhibits some activity. To deal with this issue, expiration time can be automatically renewed (for another extra 10 minutes) every time the user performs any kind of request with the following sentence:
request.session.set_expiry(request.session.get_expiry_age())
- [Django]-What are the limitations of Django's ORM?
- [Django]-How to completely uninstall a Django app?
- [Django]-Django REST Framework : "This field is required." with required=False and unique_together
- [Django]-Django: TemplateDoesNotExist (rest_framework/api.html)
- [Django]-Django Form File Field disappears on form error
- [Django]-ImportError: cannot import name 'url' from 'django.conf.urls' after upgrading to Django 4.0
4👍
In the first request, you can set the session expiry as
self.request.session['access_key'] = access_key
self.request.session['access_token'] = access_token
self.request.session.set_expiry(set_age) #in seconds
And when using the access_key and token,
try:
key = self.request.session['access_key']
except KeyError:
age = self.request.session.get_expiry_age()
if age > set_age:
#redirect to login page
- [Django]-Set Django IntegerField by choices=… name
- [Django]-How to properly use the "choices" field option in Django
- [Django]-ImportError: No module named 'django.core.urlresolvers'
0👍
I’m using Django 3.2 and i recommend using the django-auto-logout package.
It allows active time and idle time session control.
In the template you can use variables together with Javascript.
- [Django]-Django queryset filter – Q() | VS __in
- [Django]-Saving ModelForm error(User_Message could not be created because the data didn't validate)
- [Django]-Django Rest Framework File Upload