当应用程序移动到docker生产环境时,Flask-WTF CSRF验证失败

时间:2015-05-08 23:46:15

标签: flask docker csrf uwsgi flask-wtforms

我只是为我正在开发的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以及我的烧瓶应用程序,我的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,但它似乎没有任何区别。

最后,我查看了从{{form.hidden_​​tag()}}到{{form.csrf_token}}的API更改。他们仍然在最新版本的文档中引用了这两种形式。在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容器中,但我仍然得到相同的结果。

1 个答案:

答案 0 :(得分:1)

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

  

SERVER_NAME ='localhost:5000'

当我将应用程序放在生产环境中时,我不得不将其更改为:

  

SERVER_NAME ='192.168.1.66'

让应用程序显示出来。但最后我不得不完全评论它。从我的研究来看,只有当你将应用程序放在子域上时才有必要,我不是。

如果有人更深入地了解为什么会导致CSRF令牌失效,我很乐意听到它......我无法再进一步追踪它。所以现在,我完全删除了它。