如何确定用户在Django中何时有空闲超时?
我想审核用户在Django应用程序中遇到空闲超时的情况。换句话说,如果用户的会话cookie的过期日期超过settings.py中的会话\u cookie\u AGE,则用户将重定向到登录页面。当这种情况发生时,也应该进行审计。我所说的“审计”,是指一份记录应该写给我的人。审计表 目前,我已经配置了一些中间件来捕获这些事件。不幸的是,当用户被重定向到登录页面时,Django会生成一个新的cookie,因此我无法确定用户是否通过空闲超时或其他事件被带到登录页面 据我所知,我需要使用“django_会话”表。但是,此表中的记录无法与该用户关联,因为当发生重定向时,cookie中的sessionid值会重置如何确定用户在Django中何时有空闲超时?,django,session-timeout,Django,Session Timeout,我想审核用户在Django应用程序中遇到空闲超时的情况。换句话说,如果用户的会话cookie的过期日期超过settings.py中的会话\u cookie\u AGE,则用户将重定向到登录页面。当这种情况发生时,也应该进行审计。我所说的“审计”,是指一份记录应该写给我的人。审计表 目前,我已经配置了一些中间件来捕获这些事件。不幸的是,当用户被重定向到登录页面时,Django会生成一个新的cookie,因此我无法确定用户是否通过空闲超时或其他事件被带到登录页面 据我所知,我需要使用“django_
我猜我不是第一个遇到这种困境的人。有人知道如何解决这个问题吗?我不知道Django的情况,但是你能简单地创建一个非持久性cookie,它存储对站点上某个页面的最后访问时间(每次页面加载时更新cookie) 然后,在您的登录页面上,您可以检查您的用户是否有cookie,但没有会话,然后,您知道用户的会话可能已超时。由于您拥有最后一次访问站点页面的时间,您还可以根据会话的持续时间计算会话是否超时。更新: 经过一点测试,我意识到下面的代码不能回答您的问题。尽管它可以工作,并且信号处理程序被调用,
prev\u session\u data
如果存在,将不包含任何有用的信息
首先,对sessions框架的内部了解:
request.user
是AnonymousUser的一个实例)SessionStore.\u session
)中设置一个测试值;这会自动设置当前会话上的已访问
和已修改
标志SessionMiddleware
保存当前会话,有效地在django_session
表中创建一个新的session
实例(如果您使用的是默认数据库支持的会话,由django.contrib.sessions.backends.db
提供)。新会话的id保存在settings.session\u COOKIE\u NAME
COOKIE中django.contrib.auth
中的login
方法<代码>登录检查当前会话是否包含用户ID;如果是,并且ID与登录用户的ID相同,则调用SessionStore.cycle_key创建新会话密钥,同时保留会话数据。否则,将调用SessionStore.flush
,以删除所有数据并生成新会话。这两种方法都应该删除上一个会话(对于匿名用户),并调用SessionStore.create
创建新会话设置中。会话\u COOKIE\u NAME
create
时(步骤5),上一个会话的ID早已消失。正如所述,这是因为一旦会话cookie过期,浏览器就会自动删除它
在此基础上,我想我已经想出了另一种方法,它似乎满足了你的要求,尽管它的边缘仍然有点粗糙。基本上,我使用第二个长寿命的“审计”cookie来镜像会话ID,并使用一些中间件来检查cookie的存在。如有任何要求:
- 如果审核cookie和会话cookie都不存在,则这可能是一个新用户
- 如果审核cookie存在,但会话cookie不存在,则这可能是会话刚刚过期的用户
- 如果两个cookie都存在并且具有相同的值,则这是一个活动会话
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.db.models import signals
session_created = signals.Signal(providing_args=['previous_session_key', 'new_session_key'])
class SessionStore(DBStore):
"""
Override the default database session store.
The `create` method is called by the framework to:
* Create a new session, if we have a new user
* Generate a new session, if the current user's session has expired
What we want to do is override this method, so we can send a signal
whenever it is called.
"""
def create(self):
# Save the current session ID:
prev_session_id = self.session_key
# Call the superclass 'create' to create a new session:
super(SessionStore, self).create()
# We should have a new session - raise 'session_created' signal:
session_created.send(self.__class__, previous_session_key=prev_session_id, new_session_key=self.session_key)
将上面的代码保存为“customdb.py”,并将其添加到django项目中。在settings.py中,用上述文件的路径设置或替换“会话引擎”,例如:
SESSION_ENGINE = 'yourproject.customdb'
然后在中间件或models.py中,为“session_created”信号提供一个处理程序,如下所示:
from django.contrib.sessions.models import Session
from yourproject.customdb import session_created
def audit_session_expire(sender, **kwargs):
# remember that 'previous_session_key' can be None if we have a new user
try:
prev_session = Session.objects.get(kwargs['previous_session_key'])
prev_session_data = prev_session.get_decoded()
user_id = prev_session_data['_auth_user_id']
# do something with the user_id
except Session.DoesNotExist:
# new user; do something else...
session_created.connect(audit_session_expire)
不要忘记将包含models.py
的应用程序包含在已安装的应用程序中
会话\u COOKIE\u AGE=1500#25分钟
把它放在你的设置中,这样就可以解决这个问题并使会话过期。我是一名asp.net程序员,这种问题也会发生。(嗯,这是web开发,所以很相似)这就是我在asp.net中解决这个问题的方法,所以我建议这个答案。我仍然很困惑。我在哪里为audit\u session\u expire()注册接收器?
audit\u session\u expire
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.db.models import signals
session_created = signals.Signal(providing_args=['previous_session_key', 'new_session_key'])
class SessionStore(DBStore):
"""
Override the default database session store.
The `create` method is called by the framework to:
* Create a new session, if we have a new user
* Generate a new session, if the current user's session has expired
What we want to do is override this method, so we can send a signal
whenever it is called.
"""
def create(self):
# Save the current session ID:
prev_session_id = self.session_key
# Call the superclass 'create' to create a new session:
super(SessionStore, self).create()
# We should have a new session - raise 'session_created' signal:
session_created.send(self.__class__, previous_session_key=prev_session_id, new_session_key=self.session_key)
SESSION_ENGINE = 'yourproject.customdb'
from django.contrib.sessions.models import Session
from yourproject.customdb import session_created
def audit_session_expire(sender, **kwargs):
# remember that 'previous_session_key' can be None if we have a new user
try:
prev_session = Session.objects.get(kwargs['previous_session_key'])
prev_session_data = prev_session.get_decoded()
user_id = prev_session_data['_auth_user_id']
# do something with the user_id
except Session.DoesNotExist:
# new user; do something else...
session_created.connect(audit_session_expire)