我正在尝试在qjxswpoi上建议的django的内置LoginView中实现一个“记住我”复选框,但即使我调用set_expiry(0),会话仍然在this question之后到期,无论cookie过期日期(正确设置)到1969年)。
我正在使用django 2.1.7和python 3.7.2,我的SESSION_COOKIE_AGE
上唯一与会话相关的设置是settings.py
,为休息目的设置为5秒。
Django似乎使用数据库后端作为默认值。我正在使用sqlite进行开发。
这是我的观点类:
SESSION_COOKIE_AGE
这是原始的LoginView qazxsw poi方法(在上面被覆盖)
class UserLoginView(LoginView):
form_class = registration.UserLoginForm
def form_valid(self, form):
remember = form.data.get('remember_me', False)
if remember:
self.request.session.set_expiry(0)
return super(UserLoginView, self).form_valid(form)
正如您所注意到的,我正在使用自定义form_class。一个非常简单的默认表单覆盖:
form_valid
如果我在set_expiry调用之后立即使用调试器,我可以看到sesion到期时间仍然是默认的5秒:
class LoginView(SuccessURLAllowedHostsMixin, FormView):
...
def form_valid(self, form):
"""Security check complete. Log the user in."""
auth_login(self.request, form.get_user())
return HttpResponseRedirect(self.get_success_url())
...
如果我让请求完成并重定向,到达下一个视图并最终渲染我拥有的模板,我会得到类似的结果:
class UserLoginForm(AuthenticationForm):
remember_me = BooleanField(required=False)
渲染结果也是5(当前默认值)。
果然,5秒后,如果你刷新页面,django会带你回到登录界面。
我在这做错了什么?如果有人能够澄清“Web浏览器已关闭”的含义,那将会很好吗? > /project/app/views/accounts.py(64)form_valid()
-> return super(UserLoginView, self).form_valid(form)
(Pdb) self.request.session.get_expiry_age()
5
TL; DR;似乎Django不支持无限或真正未定义的到期会话时间。如果您需要延长其有效期,请将其设置为30天或更长时间。
来自...
{{ request.session.get_expiry_age }}
...
:
如果value为0,则用户的会话cookie将在用户的Web浏览器关闭时到期。
虽然这里不清楚,但是设置https://docs.djangoproject.com/en/2.2/topics/http/sessions/#django.contrib.sessions.backends.base.SessionBase.set_expiry的到期时间似乎与将其设置为Django documentation时有类似的行为:它将回退到默认的会话到期策略。这里的区别在于,当它设置为0
时,我们也推断出None
。在这两种情况下,0
都像会话最大年龄值。
我相信你可以设置一个更大的数字来解决这个问题,例如相当于100年或更长时间的事情。我的个人建议是指定用户检查“记住我”字段时的30天到期时间。当您指定大于零的正整数时,Django将不会回退到session should be expired right after the user closes the browser设置。
如果你很好奇为什么你在指定0秒到期后得到5秒,这里是从SESSION_COOKIE_AGE
函数中提取的源代码:
SESSION_COOKIE_AGE
最后的考虑: