在Heroku上使用Flask应用程序的奇怪会话行为

时间:2016-02-16 16:02:19

标签: python session heroku flask peewee

我有一个使用GitHub的OAuth API的Web应用程序,以允许应用程序的用户与GitHub交互。但是,我在会话cookie方面看到了一些非常奇怪的行为。

作为一些背景知识,我使用peewee与Heroku的Postgres服务器进行交互,并使用User这样的模型:

class User(peewee.Model):
    login = peewee.TextField(unique=False)
    token = peewee.TextField()

我正在使用GitHub OAuth文档中描述的Web应用程序流程,并且成功地使用访问令牌回调,该访问令牌存储在数据库中,也存储在会话[1]中:

@app.route('/callback')
def finishlogin():
    # I've verified that `token` and `login` are both valid at this point
    user = User.create(login=login, token=token)

    session['token'] = token

    return redirect(url_for('home'))

home的路线如下:

@app.route('/')
def home():
    if 'token' in session:
        user = User.get(token=session.get('token'))

        return 'Your login is {}'.format(user.login)
    else:
        # ...

到目前为止,这么好,这是正常的。但是,我遇到了用户登录,刷新页面并发现他们突然以其他人身份登录的情况。将请求记录到应用程序会显示,在第二个请求中,会话cookie本身发送了错误的值(即session.get('token')中的home()返回有效但不正确的值。显然,用户的浏览器无法知道任何其他会话值,所以似乎在设置不同客户端和请求之间的会话时存在一些“泄漏”。

我不确定问题可能是什么。我的数据库存储在Flask g对象中,如peewee文档中所述,并设置了before_requestteardown_request挂钩以打开和关闭数据库连接,并且我读过的文档和示例代码(我已经阅读了很多!),我似乎正在使用会话对象。我为会话商店设置了一个工作secret_key

我想知道Heroku及其路由网格是否会出现这种情况?但是,一个用户如何突然发送另一个用户的会话呢?

任何提示或建议都会受到赞赏 - 我已经盯着这个很长一段时间了,我的智慧结束了。

[1]我知道直接存储令牌是一个糟糕的设计选择。该应用程序是非公开的,这将是固定的,但是现在我想描述它存在的问题,即使它不理想。

1 个答案:

答案 0 :(得分:0)

回答我自己的问题以供将来参考。

这似乎是由Flask的默认会话Cookie行为引起的,即使用每个请求发送Set-Cookie标头,即使对于静态资产也是如此。因此,我们的本地Squid代理很乐意缓存这些请求并为每个用户重新发布Cache-Control标头。

为整个应用设置 <style name="SplashTheme" parent="AppTheme"> <item name="android:windowBackground">@drawable/splash_screen</item> </style> 标头似乎可以解决问题。