一尘不染

将应用移至Docker生产环境时,Flask-WTF CSRF验证失败

docker

我只是为我一直在开发的Flask应用设置了生产环境。

该堆栈是:

Windows Server 2012 R2 
Hyper-V VM 
    - Running Ubuntu 14.04
Docker 1.5 
    - Running Containers: 
        mysql 5.6
        nginx 1.6.3
        uwsgi 2.0.10

所以基本上我在Ubuntu中设置了一个静态IP,端口80转发到了nginx容器,在nginx和uwsgi容器之间共享了一个套接字文件的数据量,最后在mysql容器和uwsgi容器之间建立了数据库链接通讯。

我在本地开发环境中的以下实现中一直使用CSRF已有一段时间了,没有任何问题:

from flask_wtf import Form

class UserForm(Form):
    ...

然后在我的模板中:

<form>
    {{ form.hidden_tag() }}
    ...
</form>

但是,当我将应用程序(未更改)移动到上面指定的环境中时,得到:

错误的请求

CSRF令牌丢失或不正确。

作为回应,当我尝试提交表格时。我使用与pip完全相同的requirements.txt文件来设置我的Flask应用。我还验证了CSRF令牌确实在页面的HTML中。

任何人都知道为什么会这样吗?

编辑:

回答评论中的问题:生产docker容器和开发本地virtualenv中的Flask-
WTF和WTForms版本相同。这是我的需求文件,来自我的开发环境,用于在docker容器中设置我的应用程序:

Flask==0.10.1
Flask-Login==0.2.11
Flask-Mail==0.9.1
Flask-Migrate==1.2.0
Flask-MySQL==1.2
Flask-Principal==0.4.0
Flask-SQLAlchemy==2.0
Flask-Script==2.0.5
Flask-Security==1.7.4
Flask-WTF==0.10.2
Flask-WhooshAlchemy==0.55a
Jinja2==2.7.3
Mako==1.0.0
MarkupSafe==0.23
PyMySQL==0.6.2
SQLAlchemy==0.7.9
Tempita==0.5.2
WTForms==2.0.1
Werkzeug==0.9.6
Whoosh==2.6.0
alembic==0.6.7
blinker==1.3
chardet==2.2.1
decorator==3.4.0
itsdangerous==0.24
lamson==1.3.4
passlib==1.6.2
py-bcrypt==0.4
pytz==2014.9
sqlalchemy-migrate==0.7.2

话虽如此,由于安装了uWSGI和我的flask应用程序,我的docker容器中还有几个额外的模块。这是其他的。

argparse (1.2.1)
colorama (0.2.5)
docutils (0.12)
html5lib (0.999)
lockfile (0.10.2)
mock (1.0.1)
MySQL-python (1.2.5)
nose (1.3.6)
python-daemon (2.0.5)
python-modargs (1.7)
requests (2.2.1)
six (1.5.2)
urllib3 (1.7.1)
uWSGI (2.0.10)
wheel (0.24.0)
wsgiref (0.1.2)

哇,好多夫妻。也许我的包裹有冲突?

关于SECRET_KEY和CSRF_SESSION_KEY:我在config.py中定义了SECRET_KEY。导致我相信,如果不定义CSRF_SESSION_KEY,它将默认为SECRET_KEY。不过,我继续定义了CSRF_SESSION_KEY,但似乎没有任何区别。

最后,我研究了API从{{form.hidden_​​tag()}}到{{form.csrf_token}}的变化。他们在最新版本的文档中仍然引用了这两种形式。在CSRF页面上,他们拥有后者,但是在快速入门中,他们仍然拥有前者。我不确定这是怎么回事,但是可以肯定的是,我在CSRF页面上实现了该版本,如下所示:

初始化 .py:

from flask_wtf.csrf import CsrfProtect

CsrfProtect(app)

user_login.html

<form>
    {{ form.csrf_token }}
    ...
</form>

但是我仍然得到同样的回应。

正如我之前所说,Flask-WTF文档到处都是。所以我一直在尝试各种组合。在此页面底部:http : //flask-
wtf.readthedocs.org/en/latest/csrf.html他们引用了错误的导入,所以我替换了我的

从flask_wtf导入表格

从flask.ext.wtf导入表单

仍然没有骰子。不过,感谢您的评论,给了我更多尝试机会!

我还尝试将所有内容整合到一个docker容器中,但仍然得到相同的结果。


阅读 279

收藏
2020-06-17

共1个答案

一尘不染

基本上我在开发config.py文件中有这个:

SERVER_NAME =’localhost:5000’

将应用程序投入生产环境后,必须将其更改为:

SERVER_NAME =‘192.168.1.66’

让应用程序完全显示出来。但最后我不得不将其完全注释掉。根据我的研究,仅当您将应用程序放在子域中时才需要,而我不是。

如果有人对这将导致CSRF令牌无效的原因有更多的了解,我很乐意听到。.我一直无法进一步追踪。因此,到目前为止,我已将其完全删除。

2020-06-17