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

如何在5分钟内使Django会话过期?,django,session,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 no

我正在使用此功能登录用户:

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\u expiry(300)
。但这一阶段永远不会结束。我做错了什么?

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

SESSION_EXPIRE_AT_BROWSER_CLOSE = False
SESSION_COOKIE_AGE = 5 * 60 #

要将两者结合起来,请了解如何根据您的项目编写自定义中间件,这可能还不够

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

此外,如果用户在打开的浏览器页面中携带机密数据离开工作站,则存在潜在的安全问题

另外,如果用户在6分钟内阅读一个页面会怎么样?因此,在没有任何警告或任何方式延长其会话的情况下将其注销并不是很酷


考虑到这些问题,您可能会发现它很有用。

Django 1.6的更新

由于json可序列化,下面的中间件代码在Django 1.6及以上版本中无法工作。要使其在Django的所有版本中都能工作,请将会话序列化程序放入

设置.py

#Handle session is not Json Serializable
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
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()
# 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
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
上面的序列化程序示例适用于Django 1.6。请搜索其他版本。谢谢

创建中间件.py

#Handle session is not Json Serializable
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
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()
# 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
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
更新您的设置。py

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

    'app_name.middleware.AutoLogout', 
]

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

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

这对我有用

设置.py 中间件.py
Django 1.9

编辑您的设置.py并添加以下内容:

# SESSION AGE 5 Minutes
SESSION_COOKIE_AGE = 5*60

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

  • 首先,您需要使用以下命令安装django会话超时:

    pip安装django会话超时

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

    中间件\u类=[
    ...
    “django.contrib.sessions.middleware.SessionMiddleware”,
    “django_会话_超时.中间件.SessionTimeoutMiddleware”,
    ...
    ]

  • 最后,您需要在settings.py的末尾添加会话\u EXPIRE\u秒:

    SESSION_EXPIRE_SECONDS=300#300 SECONDS=5分钟

默认情况下,会话将在会话开始后X秒过期。要在最后一个活动结束X秒后使会话过期,请使用以下设置:


SESSION\u EXPIRE\u在最后一次活动=True之后

更新@jhonnylopez的答案,并在一段时间不活动后而不是在给定时间后注销:

设置.py

#Handle session is not Json Serializable
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
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()
# 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
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
中间件.py

#Handle session is not Json Serializable
SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
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()
# 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
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

如果您正在寻找5分钟后的简单过期,并且不关心提示用户或允许他们延长会话,那么django会话超时可以很好地工作

pip install django-session-timeout
虽然这是一个5分钟后会话到期的快速修复方法,可以重定向到指定页面(注销),但它无助于解决本帖中关于警告用户或提供会话扩展机会的一些其他问题。最后一个活动设置设置为True时,它将继续基于活动扩展会话,但是,如果他们正在阅读页面或填写表单的时间超过5分钟,它会将他们注销,这可能会导致用户出现问题,具体取决于您的站点功能

此处有更多文档:

我还没有实施,但计划下一步。如果您需要添加提示用户并允许他们选择扩展会话的功能,其他一些帖子建议使用django会话安全性


如果您不想添加自己的中间件,那么这些都是很好的替代方法。

在调用login()之前需要设置会话,正如Dmitry Nikitin所指出的那样。您还需要在设置文件中添加
SESSION\u SAVE\u EVERY\u REQUEST=True
。此设置将随每个请求不断更新到期时间。因此,在5分钟不活动后,会话将过期。

我已经回答了同样的问题,这里是链接。如果您有任何澄清,请告诉我如果用户正在打开应用程序,我不希望会话过期。如果用户在5分钟内没有打开应用程序,我希望会话过期。是的,这就是我的答案。如果用户空闲,则将自动注销。你想让我把整个答案都贴在这里吗?是的,就这样。我会将您的答案标记为正确。如果用户正在打开应用程序,我不希望会话过期。如果用户在5分钟内没有打开应用程序,我希望会话过期。请注意,我的中间件代码检查request.user.is_authenticated()。@hec如果您设置会话序列化程序来修复
不可json序列化的
,或者您可以将datetime.now()更改为time.time()。对条件逻辑进行其他小的相关更改,它就可以在JSON序列化程序上工作。@Hec也可以。会话序列化程序不仅在datetime中用于全局。谢谢……:)@catherine,为什么你的代码和我链接的在你之前一年写的代码不一样?PickerSerializer太棒了!(Django 1.8-路径相同)尝试了Django会话安全性。安装如风,工作如神。感谢您制作了如此精彩的模块!这个包在使用Django 2.2时运行良好。对文档中提供的说明进行了一些必要的调整,因为它是为Django pre-1.10编写的:-
session\u security.middleware.SessionSecurityMiddleware
被添加到
middleware
列表中,而不是不再存在的
middleware\u类
“django.template.context\u processors.request”
,而不是必须添加到li的“django.core.context\u processors.request”