烧瓶永久会话:在哪里定义它们?
Posted
技术标签:
【中文标题】烧瓶永久会话:在哪里定义它们?【英文标题】:Flask permanent session: where to define them? 【发布时间】:2016-03-11 03:24:42 【问题描述】:默认情况下,Flask 使用 volatile 会话,这意味着会话 cookie 设置为在浏览器关闭时过期。为了使用永久会话,它将使用具有已定义过期日期的 cookie,应设置session.permanent = True
,就像mentioned in this question. 一样,过期日期将基于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,可能需要设置不同的生命周期。实现这一目标的最佳方法是什么?
【问题讨论】:
【参考方案1】:我很惊讶没有回答这个问题。似乎应该有某种类型的配置变量SESSION_PERMANENT = True
。但不幸的是没有。正如您所提到的,这是最好的方法。
@app.before_request
def make_session_permanent():
session.permanent = True
【讨论】:
是 config['PERMANENT_SESSION_LIFETIME'] 值以秒还是毫秒为单位? @dashesy,您指的是Flask-Session 扩展中的配置。在 vanilla Flask 会话管理中,config['SESSION_PERMANENT']
不存在,甚至在 master 分支中也不存在。
@RandomCOSMOS app.config['PERMANENT_SESSION_LIFETIME']
的值以秒为单位,您可以在文档中看到:flask.palletsprojects.com/en/2.0.x/config/…【参考方案2】:
你应该使用PERMANENT_SESSION_LIFETIME
和session.permanent
吗?
您真正想要做的可能是使用户的登录状态过期。但是,此配置会使包含用户登录状态以及(可能)存储在session
中的其他一些数据的会话对象/cookie 过期。
需要设置session.permanent
吗?
根据Flask's doc:
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
。
但是,如果您打算仅在用户登录时分配它,请通过检查用户如何绕过登录路径进行登录来保持警惕。例如,通过注册。
【讨论】:
非常详细且有用的答案,您能否详细说明用户如何通过注册绕过登录路线? @oeter 假设您的服务的用户体验旨在让用户在注册后进入登录状态,因此用户无需在注册后立即登录。然后,您服务中的注册逻辑可能会包含授予会话的逻辑,该逻辑可能与登录逻辑共享,也可能不共享。【参考方案3】:我选择你说的“login_user()”
@asset.route('/login', methods=['GET', 'POST'])
def login():
#After Verify the validity of username and password
session.permanent = True
如果它设置在 app.before_request,这将导致设置它们太多次。
【讨论】:
您是否考虑过session['_permanent']
可以设置为false或从客户端发出的请求中删除?这将导致绕过过期时间的验证。以上是关于烧瓶永久会话:在哪里定义它们?的主要内容,如果未能解决你的问题,请参考以下文章