Django,如何获得cookie过期的时间
Django, how to get the time until a cookie expires
在标记为 dup 之前(我相信很多答案都是不正确的,因为):
根据我的研究:
request.session.get_expiry_age
returns cookie 的总生命周期,而不是从现在到过期的时间。它总是 returns 相同的值,无论剩余多少时间。
- 同样
get_expiry_date
将总生命周期加到现在时间。它总是在调用时增加。
因此他们都没有帮助。
settings.SESSION_SAVE_EVERY_REQUEST
在每次请求时刷新 cookie,这不是我想要实现的。
get_session_cookie_age()
只有 returns settings.SESSION_COOKIE_AGE 的值,如源代码所示:
def get_session_cookie_age(self):
return settings.SESSION_COOKIE_AGE
我使用 cached_db
会话后端。缓存的部分none无效,因为它每次都必须保存cookie,因此SESSION_SAVE_EVERY_REQUEST
不适用。我问这个问题的原因是因为我希望仅在剩余时间低于阈值时刷新 cookie,因此有些歇斯底里(具有缓存和自动刷新的好处)。
由于 get_expiry_age
/get_expiry_date
的行为,我的代码无法正常工作,如上所述:
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
class SessionExpiry(MiddlewareMixin):
def process_request(self, request):
"""Automatically refresh a session expirary at a certain limit.
If request.session age goes below settings.SESSION_REFRESH, then
set the sessions expirary age to settings.SESSION_COOKIE_AGE. The
session is not refreshed every time to have the caching benefits of
the cached_db backend.
"""
try:
empty = request.session.is_empty()
except AttributeError:
return None
if (empty or not getattr(settings, 'SESSION_REFRESH', None)):
return None
if request.session.get_expiry_age() < settings.SESSION_REFRESH:
request.session.set_expiry(settings.SESSION_COOKIE_AGE)
return None
这是 Django 在设计和文档方面令人困惑的一个领域。弄清楚发生了什么的最简单方法是查看 source code.
要获得您想要的内容,您需要将自定义到期时间设置为 datetime
。如果你使用秒(包括默认的SESSION_COOKIE_AGE
)被解释为从现在开始的秒数;也就是说,无论何时你问。
因此要设置到期时间,请使用:
# Using timedelta will cause the session to save the expiration time as a datetime.
request.session.set_expiry(timedelta(seconds=settings.SESSION_COOKIE_AGE))
如果您这样做,对 get_expiry_age()
的调用将 return 当前日期时间与设置为到期日期时间之间的实际差异。
请务必注意 set_expiry()
文档中的警告:“请注意,只有在使用 PickleSerializer
时,datetime
和 timedelta
值才可序列化。”
从Django票子过来的。这是我想出的避免需要 pickle 序列化器和 SESSION_SAVE_EVERY_REQUEST 的方法。因此,我们可以使用纯时间戳而不是 datetime
,并且由于 set_expire
不支持它,我们将添加另一个会话密钥来存储它。
class RefreshSessionMiddleware(middleware.SessionMiddleware):
def process_response(self, request, response):
session = request.session
if not (session.is_empty() or session.get_expire_at_browser_close()):
expiry = session.get('_session_expire_at_ts')
now_ts = int(time.time())
cookie_lifetime = session.get_expiry_age()
if expiry is None or now_ts + cookie_lifetime / 2 > expiry:
# This will set modified flag and update the cookie expiration time
session['_session_expire_at_ts'] = now_ts + cookie_lifetime
return super().process_response(request, response)
在标记为 dup 之前(我相信很多答案都是不正确的,因为): 根据我的研究:
request.session.get_expiry_age
returns cookie 的总生命周期,而不是从现在到过期的时间。它总是 returns 相同的值,无论剩余多少时间。- 同样
get_expiry_date
将总生命周期加到现在时间。它总是在调用时增加。 因此他们都没有帮助。
settings.SESSION_SAVE_EVERY_REQUEST
在每次请求时刷新 cookie,这不是我想要实现的。
get_session_cookie_age()
只有 returns settings.SESSION_COOKIE_AGE 的值,如源代码所示:
def get_session_cookie_age(self):
return settings.SESSION_COOKIE_AGE
我使用 cached_db
会话后端。缓存的部分none无效,因为它每次都必须保存cookie,因此SESSION_SAVE_EVERY_REQUEST
不适用。我问这个问题的原因是因为我希望仅在剩余时间低于阈值时刷新 cookie,因此有些歇斯底里(具有缓存和自动刷新的好处)。
由于 get_expiry_age
/get_expiry_date
的行为,我的代码无法正常工作,如上所述:
from django.conf import settings
from django.utils.deprecation import MiddlewareMixin
class SessionExpiry(MiddlewareMixin):
def process_request(self, request):
"""Automatically refresh a session expirary at a certain limit.
If request.session age goes below settings.SESSION_REFRESH, then
set the sessions expirary age to settings.SESSION_COOKIE_AGE. The
session is not refreshed every time to have the caching benefits of
the cached_db backend.
"""
try:
empty = request.session.is_empty()
except AttributeError:
return None
if (empty or not getattr(settings, 'SESSION_REFRESH', None)):
return None
if request.session.get_expiry_age() < settings.SESSION_REFRESH:
request.session.set_expiry(settings.SESSION_COOKIE_AGE)
return None
这是 Django 在设计和文档方面令人困惑的一个领域。弄清楚发生了什么的最简单方法是查看 source code.
要获得您想要的内容,您需要将自定义到期时间设置为 datetime
。如果你使用秒(包括默认的SESSION_COOKIE_AGE
)被解释为从现在开始的秒数;也就是说,无论何时你问。
因此要设置到期时间,请使用:
# Using timedelta will cause the session to save the expiration time as a datetime.
request.session.set_expiry(timedelta(seconds=settings.SESSION_COOKIE_AGE))
如果您这样做,对 get_expiry_age()
的调用将 return 当前日期时间与设置为到期日期时间之间的实际差异。
请务必注意 set_expiry()
文档中的警告:“请注意,只有在使用 PickleSerializer
时,datetime
和 timedelta
值才可序列化。”
从Django票子过来的。这是我想出的避免需要 pickle 序列化器和 SESSION_SAVE_EVERY_REQUEST 的方法。因此,我们可以使用纯时间戳而不是 datetime
,并且由于 set_expire
不支持它,我们将添加另一个会话密钥来存储它。
class RefreshSessionMiddleware(middleware.SessionMiddleware):
def process_response(self, request, response):
session = request.session
if not (session.is_empty() or session.get_expire_at_browser_close()):
expiry = session.get('_session_expire_at_ts')
now_ts = int(time.time())
cookie_lifetime = session.get_expiry_age()
if expiry is None or now_ts + cookie_lifetime / 2 > expiry:
# This will set modified flag and update the cookie expiration time
session['_session_expire_at_ts'] = now_ts + cookie_lifetime
return super().process_response(request, response)