出于安全考虑,我将SESSION_EXPIRE_AT_BROWSER_CLOSE设置为true。
但是,浏览器长度的cookie(一旦用户关闭其浏览器就会过期的cookie)没有过期时间,那么SESSION_COOKIE_AGE没有效果(是的,我检查它)。但我想在不活动时设置注销/超时加上注销浏览结束。
我的问题是,在浏览器长度的Cookie方案中实施非活动超时/注销的最佳方法是什么?
答案 0 :(得分:18)
正如您所解释的那样,SESSION_EXPIRE_AT_BROWSER_CLOSE和SESSION_COOKIE_AGE不兼容。当您为cookie设置过期日期时,此cookie将变为浏览器长度的cookie。
然后,为了达到您想要的行为,您应该将SESSION_EXPIRE_AT_BROWSER_CLOSE设置为True并控制手动过期超时。
手动控制过期超时的优雅方式是:
超时自定义中间件可能如下所示:
# 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
古代Django版本的解决方案(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
请务必启用sessions以存储lastRequest
。
这个解决方案是我编写和测试的,现在正在我的网站上工作。此代码具有GNU许可证;)
关于django 1.6的新内容(......两年后......)
如果您使用PickleSerializer,则日期时间和时间范围值仅可序列化。如果没有,也许简单的解决方案是translate datetime to unix timestamp and back。可以在此翻译下方发布。
<强>被修改强>
django-session-security app提供了一种注销非活动身份验证用户的机制。看一看。