Flask 永久会话:在哪里定义它们?

新手上路,请多包涵

默认情况下,Flask 使用易失性会话,这意味着会话 cookie 设置为在浏览器关闭时过期。为了使用永久会话,它将使用具有已定义到期日期的 cookie,应该设置 session.permanent = True ,如 该问题中所述。 ,到期日期将根据 config['PERMANENT_SESSION_LIFETIME'] 设置。

我很惊讶会话生命周期是在配置文件中定义的,但是不可能通过配置请求使用永久会话,例如 config['USE_PERMANENT_SESSION'] = True 。但就这样吧。

我的问题是:如果您 确实 想要永久会话,那么定义它们的最佳位置是什么?它是否在上述问题中提出的 @app.before_request 函数中?但这是否意味着在每次请求时都要重新设置它?似乎一旦设置, session.permanent 在会话结束之前一直保持为真。

永久会话通常 在登录后 使用,所以请求它们的最佳位置可能是在处理 login_user() 时?那么最好的策略是对所有匿名页面使用易失性会话 cookie,并通过在登录时执行 session.permanent = True 切换到永久会话吗?

人们可能希望根据它是普通的 session cookie 还是 remember_me cookie 来设置不同的生命周期。实现这一目标的最佳方法是什么?

原文由 patb 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

我很惊讶没有回答这个问题。似乎应该有某种类型的配置变量 SESSION_PERMANENT = True 。但不幸的是没有。正如您提到的,这是最好的方法。

 @app.before_request
def make_session_permanent():
    session.permanent = True

原文由 mikey8989 发布,翻译遵循 CC BY-SA 3.0 许可协议

你应该使用 PERMANENT_SESSION_LIFETIMEsession.permanent 吗?

您真正想要做的可能是使用户的登录状态过期。但是,此配置会使包含用户登录状态以及(可能)存储在 session 中的其他一些数据的会话对象/cookie 过期。

您需要设置 session.permanent 吗?

根据 Flask 的文档

Flask 的默认 cookie 实现验证加密签名不早于此值。

session.permanent 是 --- 的附加 PERMANENT_SESSION_LIFETIME 。有时不将 session.permanent 设置为 True 也没关系。

如果您不设置 session.permanent ,会话 cookie 的生命周期将不受 PERMANENT_SESSION_LIFETIME 的影响。但是 Flask 会查看 PERMANENT_SESSION_LIFETIME 和会话 cookie 中的时间戳,以查看会话 cookie 是否仍然有效。如果时间戳比 PERMANENT_SESSION_LIFETIME 指定的时间太早,它将被忽略。但是 cookie 仍然存在。

这就是 Flask 忽略会话 cookie 的方式:

 def open_session(self, app, request):
    s = self.get_signing_serializer(app)
    if s is None:
        return None
    val = request.cookies.get(app.session_cookie_name)
    if not val:
        return self.session_class()
    max_age = total_seconds(app.permanent_session_lifetime)
    try:
        data = s.loads(val, max_age=max_age)
        return self.session_class(data)
    except BadSignature:
        return self.session_class()

如果您设置 session.permanent=True ,验证仍将完成。而且,会话 cookie 将在 PERMANENT_SESSION_LIFETIME 之后过期并从浏览器中删除。

这就是 PERMANENT_SESSION_LIFETIME 控制 cookie 过期的方式:

 def get_expiration_time(self, app, session):
    if session.permanent:
        return datetime.utcnow() + app.permanent_session_lifetime

def save_session(self, app, session, response):
    ...
    expires = self.get_expiration_time(app, session)
    val = self.get_signing_serializer(app).dumps(dict(session))
    response.set_cookie(
        app.session_cookie_name,
        val,
        expires=expires,
        httponly=httponly,
        domain=domain,
        path=path,
        secure=secure,
        samesite=samesite
    )

您是否需要为每个请求设置 session.permanent

session.permanent 默认情况下实际上是 session['_permanent'] 。它的值将保留在 session 。但是,如果您打算仅在用户登录时分配它,请通过检查用户如何绕过登录路由来登录来保持警惕。例如,通过注册。

原文由 Kaiwen Sun 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题