如何在烧瓶中使用g.user global

Mit*_*ops 56 python jinja2 flask flask-login

据我了解Flask中的g变量,它应该为我提供一个存储数据的全局位置,例如在登录后保存当前用户.它是否正确?

我希望我的导航在整个站点登录后显示我的用户名.

我的观点包含

from Flask import g #among other things
Run Code Online (Sandbox Code Playgroud)

在登录期间,我分配

user = User.query.filter_by(username = form.username.data).first()
if validate(user):
    session['logged_in'] = True
    g.user = user
Run Code Online (Sandbox Code Playgroud)

我似乎无法访问g.user.相反,当我的base.html模板具有以下内容时......

<ul class="nav">
    {% if session['logged_in'] %}
        <li class="inactive">logged in as {{ g.user.username }}</li>
    {% endif %}
</ul>
Run Code Online (Sandbox Code Playgroud)

我收到错误:

jinja2.exceptions.UndefinedError
UndefinedError: 'flask.ctx._RequestGlobals object' has no attribute 'user'
Run Code Online (Sandbox Code Playgroud)

登录否则工作正常.我错过了什么?

Sea*_*ira 76

g是一个本地线程,是按请求(请参阅代理注释).该session一个线程局部,但在默认情况下被保存到一个MAC-签署cookie,并发送给客户端.

您遇到的问题session是在每个请求上重建(因为它被发送到客户端并且客户端将其发送回给我们),而设置的数据g仅在请求的生命周期内可用.

最简单的事情(注意simple != secure-如果你需要确保看看烧瓶登录)是简单地将用户的ID添加到会话,并加载每个请求的用户:

@app.before_request
def load_user():
    if session["user_id"]:
        user = User.query.filter_by(username=session["user_id"]).first()
    else:
        user = {"name": "Guest"}  # Make it better, use an anonymous User instead

    g.user = user
Run Code Online (Sandbox Code Playgroud)

  • @Mittenchops - Flask-Login仍然使用`session` - 它只处理管理登录/注销的所有极端情况,在必要时强制重新进行身份验证等.使这些角落案例错误的可能性使您的应用程序不太安全.`g`无论如何都是安全的 - 它不是由用户提供的数据构成的,因此可能被认为是"安全的". (3认同)
  • 由于我对Web开发有点新意,我可以检查一下我是否理解了一切?如果'value'是一个字符串(或者可以存储为字符串的东西),我应该使用session ['key'] ='value',并使用g.key = value是值更复杂的'python'对象(或者不能作为字符串存储的东西).并且会话将被存储在每个连接中"直到浏览器关闭",并且将针对每个请求删除g,即对于在地址栏中按下的每个"输入". (3认同)
  • 谢谢,肖恩,它为我澄清了g发生了什么.我不认为你有关于会话的不安全部分以及如何使用Flask-Login更好地实现这一点的进一步评论?解决方案是否如使用Flask-Login那么简单,然后使用session []变量是安全的?您是否建议不要使用g,如我链接的教程中所示? (2认同)
  • @Mittenchops - 只要您存储的是可序列化的`session`可能是一个更好的选择(因为`g`在每个请求结束时被拆除,而'session`在请求之间被保留).因此,假设`User`可以被序列化,你可以这样做:`if"user"不在会话中:#query database`并避免多次调用DB(未增强的`g`将需要在每个请求上调用DB因为它总是重新建造). (2认同)
  • @Kevin - 修复了!感谢您帮助保持最新的答案! (2认同)