即使在 Flask 中关闭浏览器后,如何将一个会话变量存储一段时间?

How do I store one session variable for some time even after closing the browser in Flask?

我正在使用 Flask-Login 的函数 login() 和 remember=True。

这工作正常。但最近我实现了双因素身份验证,用户必须下载身份验证器应用程序才能登录。

我创建了自己的 @tfa_required 装饰器,它使用 @login_required 以防用户启用 TFA。我跟踪登录状态的方法是使用一个名为 auth_level 的会话变量来了解用户是否使用 TFA 成功登录。 (附上代码片段)。

假设用户登录浏览器然后关闭它。他仍会登录(因为他使用 remember = True 登录),但他将不得不再次输入 TFA(auth_level=1 -- 意味着 TFA 尚未成功 -- 现在而不是 auth_level=2 ).

我真正想要的是只要 Flask-Login 记得用户登录就存储 auth_level 会话变量,即使在关闭浏览器之后也是如此。

据我了解,Flask-Login 使用不同的会话来存储与登录相关的变量,以便用户在一段时间内仍处于登录状态。

如何让客户端在关闭浏览器后仍记得 auth_level

谢谢。

# Decorator for TFA-required views
def tfa_login_required(f):
    """Implement additional TFA checking, on top of login_required.

    TFA is only checked if it has been activated for the user.
    """
    @wraps(f)
    @login_required
    def decorated_function(*args, **kwargs):
        # if the user is authenticated and has tfa enabled but not tfa passed
        if (
            current_user.tfa_enabled
            and session.get('auth_level') != 2
        ):
            return redirect(url_for('auth.login_view'))
        # if authenticated proceed normally
        else:
            return f(*args, **kwargs)
    return decorated_function

使用 login_required 的示例 没有 tfa_required:

@auth.route('/logout/')
@login_required
def logout():
    logout_user()
    session['auth_level'] = 0
    session.modified = True
    return redirect(url_for('main.home'))

同时使用 tfa_required 和 login_required 的示例:

@main.route('/some_route/', methods=['GET'])
@tfa_login_required
def some_route():
    do_some_work_that_requires_full_authentication()

您可能正在寻找 this

默认情况下,如果选项卡关闭,Flask 会删除所有会话数据。为了使其永久化,请执行以下操作:

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

我最终使用 Flask-Login cookie 本身将变量包含在 Flask-Login cookie 中。作为参考,这里是代码:

from flask_login import (
....
COOKIE_DURATION,
COOKIE_SECURE,
COOKIE_HTTPONLY,
encode_cookie,
)

在视图函数中,我没有返回 url_for(...),而是使用 make_response() 创建响应对象并使用以下设置响应 cookie:

    response = make_response(redirect(url_for('...')))

    # Setting cookie similar to Flask Login way of setting its cookies
    duration = current_app.config.get('REMEMBER_COOKIE_DURATION', COOKIE_DURATION)
    secure = current_app.config.get('REMEMBER_COOKIE_SECURE', COOKIE_SECURE)
    httponly = current_app.config.get('REMEMBER_COOKIE_HTTPONLY', COOKIE_HTTPONLY)
    expires = duration + datetime.utcnow()

    # encode additional data to ensure that the user cannot simply use the value
    # from the remember cookie
    data = encode_cookie(str(session['_user_id']) + '_cookie_variable')

    response.set_cookie(
        'cookie_variable',
        value=data,
        expires=expires,
        secure=secure,
        httponly=httponly
    )
    return response