使用Gunicorn和Flask时CSRF令牌错误

时间:2019-12-16 16:39:32

标签: flask gunicorn flask-wtforms

我已经开发了一个Web应用程序,其中包含供用户登录和注册的功能。我已经按照文档和教程完成了所有工作,并且一切与flask服务器都可以正常工作。

问题是:我使用gunicorn并启动Web服务器,在几种不同的浏览器(Linux上为Brave和Firefox,在Android上为Brave)上打开地址(localhost:8000),我只能登录(单个或多个)不同的用户)。当我尝试从另一个请求中这样做时,它会抛出400错误请求(缺少CSRF会话令牌或CSRF会话令牌不匹配)。

现在,使用Flasks Server不会发生这种情况。它仅在使用Gunicorn时发生。

我已将应用程序部署到Heroku(使用免费计划),并且希望多个用户同时登录。这会在我的应用具有的所有其他形式上发生。

所有环境变量,秘密密钥均已正确配置,使用Flask Server时,所有功能均按预期工作。使用Gunicorn不会导致任何其他问题。有时,从单个客户端登录也不起作用。

任何帮助将不胜感激。我已经看过其他相关的主题/问题,但他们没有提及我遇到的问题

1 个答案:

答案 0 :(得分:1)

抱歉回复晚了(也许以后能帮到人)

简短的回答:
使用:

with app.app_context():
    your code

而不是:

app.app_context().push()

永不关闭

长答案:

我猜你使用 Flask-WTF 来管理 CSRF, 如果是,则 generate_csrf 函数中有一个 if 块(https://github.com/wtforms/flask-wtf/blob/0.15.x/src/flask_wtf/csrf.py#L53),它在生成新的 CSRF 令牌之前检查 flask g 变量。它工作得很好,但是当 g 变量没有在每个新请求上重新初始化时(原因见下文),它会在尝试登录的不同用户之间造成冲突。

不重新初始化flask g变量的主要原因是手动推送的应用程序上下文(通常通过:app.app_context().push())但未关闭,在这种情况下,应用程序上下文永远不会被拆除,请参阅:Flask app.teardown_appcontext not being called when DEBUG is false

最后,我认为 Flask DEBUG 模式中有一些东西,它强制拆除应用程序上下文并重新初始化 g 变量。