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:
- Auto log-out after X amount of time since log-in
- 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.