我正在尝试在django内置的LoginView中实现“记住我”复选框,如this question上所建议,但是即使我调用set_expiry(0),会话仍会在SESSION_COOKIE_AGE
之后到期,不管cookie的过期日期(正确设置为1969)。
我正在将django 2.1.7与python 3.7.2结合使用,并且settings.py
上唯一与会话相关的设置是SESSION_COOKIE_AGE
,出于休息目的,该设置设置为5秒。 >
Django似乎默认使用数据库后端。我正在使用sqlite进行开发。
这是我的视图类:
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)
这是原始 LoginView form_valid
方法(上面已被覆盖)
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())
...
您注意到,我正在使用自定义的form_class。默认形式的一个非常简单的替代:
class UserLoginForm(AuthenticationForm):
remember_me = BooleanField(required=False)
如果我在set_expiry调用后立即使用调试器,则可以看到sesion的到期时间仍然是默认的5秒:
> /project/app/views/accounts.py(64)form_valid()
-> return super(UserLoginView, self).form_valid(form)
(Pdb) self.request.session.get_expiry_age()
5
如果我让请求完成并重定向,到达下一个视图并最终在有模板的地方渲染模板,我会得到类似的结果:
...
{{ request.session.get_expiry_age }}
...
渲染的结果也是5(当前默认值)。
果然,在5秒钟后,如果刷新页面,django将带您返回登录屏幕。
我在这里做错了什么?如果有人可以澄清“ Web浏览器已关闭”在这里意味着什么,那将是很好的? https://docs.djangoproject.com/en/2.2/topics/http/sessions/#django.contrib.sessions.backends.base.SessionBase.set_expiry
答案 0 :(得分:2)
TL; DR; Seems like Django does not offer support for infinite or truly undefined expiry session times. Set it to 30 days or greater if you need to extend its validity.
如果该值为0,则当用户关闭Web浏览器时,该用户的会话Cookie将会过期。
尽管此处还不清楚,但将过期时间设置为0
时似乎具有类似的行为:它将回退到默认的会话过期策略。此处的区别在于,将其设置为None
时,我们还推断出session should be expired right after the user closes the browser。在这两种情况下,0
的工作方式都类似于会话的最大年龄值。
我相信您可以设置更大的数字来解决此问题,例如,相当于100年或更长的时间。我个人的建议是在用户选中“记住我”字段时指定30天的到期时间。当您指定大于零的正整数时,Django将不会退回到SESSION_COOKIE_AGE
设置。
如果您好奇为什么即使指定了0秒的有效期仍要获得5秒的时间,以下是从SESSION_COOKIE_AGE
函数中提取的源代码:
get_expiry_age
最终注意事项: