如何在5分钟内过期Django会话?

时间:2013-02-12 10:45:08

标签: django session

我用它来登录用户:

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))

我希望会话在5分钟后过期,因此我在上面的视图中添加了request.session.set_expiry(300)。但会议永远不会到期。我做错了什么?

10 个答案:

答案 0 :(得分:40)

要使会话到期有两个参数,SESSION_EXPIRE_AT_BROWSER_CLOSESESSION_COOKIE_AGE。 如果您想在5分钟后过期,您的设置应如下:

SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_COOKIE_AGE = 5 * 60 #

要结合两者,请了解如何编写自定义中间件"Is there a way to combine behavior of SESSION_EXPIRE_AT_BROWSER_CLOSE and SESSION_COOKIE_AGE"

答案 1 :(得分:34)

Django 1.6的更新

由于json可序列化,下面的中间件代码无法在Django 1.6及更高版本中运行。要使它在所有版本的Django中工作,请放置会话序列化器。

<强> settings.py

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

上面的序列化器示例适用于Django 1.6。请搜索其他版本。感谢...

创建 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()

更新 settings.py

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

    'app_name.middleware.AutoLogout', 
]

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

答案 2 :(得分:14)

Django 1.9

修改 settings.py 并添加以下内容:

# SESSION AGE 5 Minutes
SESSION_COOKIE_AGE = 5*60

答案 3 :(得分:12)

根据您的项目,这可能还不够。

例如,如果用户花费6分钟填写表单并点击“保存”,该怎么办?浏览器将被重定向到登录页面,表单数据将丢失。

此外,如果用户将其机密数据留在浏览器的已打开页面中,则存在潜在的安全问题。

另外,如果用户在6分钟内阅读页面怎么办?如果没有任何警告或以任何方式延长他的会话,他就不会真的很酷......

考虑到这些问题,您可能会发现django-session-security很有用。

答案 4 :(得分:2)

在调用login()之前设置所需的会话时间!

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

答案 5 :(得分:2)

这对我有用

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

答案 6 :(得分:1)

我使用Django 2.1.7,而终止django会话的最简单方法是:

  • 首先,您需要使用以下命令安装django-session-timeout:

    pip install django-session-timeout

  • 您无需在settings.py中更新SessionTimeoutMiddleware

    MIDDLEWARE_CLASSES = [ ... 'django.contrib.sessions.middleware.SessionMiddleware', 'django_session_timeout.middleware.SessionTimeoutMiddleware', ... ]

  • 最后,您需要在settings.py的末尾添加SESSION_EXPIRE_SECONDS。

    SESSION_EXPIRE_SECONDS = 600 # 600 seconds = 5 minutes

默认情况下,会话将在会话开始后X秒钟后过期。要使会话在上一次活动后的X秒后过期,请使用以下设置:

SESSION_EXPIRE_AFTER_LAST_ACTIVITY = True

答案 7 :(得分:1)

使@jhonnylopez的答案保持最新,并在一段时间不活动后而不是在给定时间后退出:

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

答案 8 :(得分:1)

如果您希望在5分钟后到期,并且不希望提示用户或允许他们延长会话时间,则django-session-timeout效果很好。

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

虽然这是5分钟后会话过期的快速解决方案,并且可以重定向到指定的页面(注销),但对于警告用户或给予扩展机会的这篇文章中提到的其他一些问题没有帮助一个会话。将上一个活动设置为True后,它将根据活动继续扩展会话,但是,如果他们正在阅读页面或填写表单的时间超过5分钟,则将其注销,这可能会导致您的问题用户取决于您的网站功能。

此处的其他文档:https://pypi.org/project/django-session-timeout/

我还没有实现它,但是计划下一步。如果您需要其他功能来提示用户并允许他们选择扩展会话,则其他一些帖子建议使用django-session-security。

如果您不打算自己添加中间件,那么这是个不错的选择。

答案 9 :(得分:0)

如Dmitry Nikitin所指出的,需要在调用login()之前设置会话。另外,您需要在设置文件中添加SESSION_SAVE_EVERY_REQUEST = True。此设置将随着每个请求不断更新到期时间。因此,闲置5分钟后,会话将终止。