代码之家  ›  专栏  ›  技术社区  ›  user1961

如何在整个应用程序中重复检查烧瓶中的会话变量?

  •  -1
  • user1961  · 技术社区  · 4 年前

    我正在寻找一种有效的方法来检查每个视图的会话变量。我可以按照下面的文档进行操作,但是否有全局函数或装饰器可以提取 username 不重复同样的台词?

    @app.route('/')
    def index():
        if 'username' in session:   # this is repeated in every view
            username = session['username'] # this is repeated in every view
        return 'You are not logged in'
    
    0 回复  |  直到 4 年前
        1
  •  2
  •   Detlef    4 年前

    你的猜测是正确的。装饰器是审查会话并对结果作出反应的一种方式。在下面的例子中,如果用户没有登录,则会根据decorator将用户重定向到适当的路由。如果用户名存储在会话中,则会调用decorated路由。

    如果登录对于相应的路由是可选的,那么它是公共的,不需要decorator。但可能需要询问用户是否已登录。

    from flask import (
        redirect,
        session,
        url_for
    )
    from functools import wraps
    
    # ...
    
    def is_authenticated():
        username = session.get('username')
        return username and len(username.strip()) > 0
    
    def login_required(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            if not is_authenticated():
                return redirect(url_for('login'))
            return f(*args, **kwargs)
        return wrapper
    
    # Add the state query function to the jinja context.
    app.jinja_env.globals.update(is_authenticated=is_authenticated)
    
    @app.route('/login', methods=['GET', 'POST'])
    def login():
        # your login code here!
    
    @app.route('/secret')
    @login_required
    def secret():
        return 'You are logged in.'
    
    @app.route('/public')
    def public():
        if is_authenticated():
            return 'User is authenticated'
        return 'User is not authenticated'
    

    此代码用于在模板中检查用户是否已登录。

        {% if is_authenticated() %}
          User is authenticated.
        {% else %}
          User is not authenticated.
        {% endif %}
    

    如果您真的想在每条路由之前询问会话变量 before_request decorator可能是一个解决方案。在这种情况下,无法避免将变量存储在 g object 在你的路线上使用它们。然而,这超出了您的示例范围,或者不必要地使代码复杂化,因为只需要使用额外的数据。
    我认为我给出的代码对于简单的目的来说应该足够了。 对于更复杂的环境,我建议您查看 Flask-Login Flask-Security