我有一个CSRF保护的表单在开发环境中完美运行(Flask运行服务器本身的app.run
),但在Apache中通过mod_wsgi
运行应用程序时失败。我使用的版本是:由于会话重置导致的Apache Flask中的CSRF令牌不匹配
Server version: Apache/2.4.4 (Unix)
Python 2.7.3
Flask==0.10.1
Flask-WTF==0.9.5
WTForms==2.0
Flask-KVSession==0.4
simplekv==0.8.4
,它失败的原因是表单验证过程中csrf_token
不匹配。我在视图的开头记录了flask.session
和flask.request.form
的内容,并在视图结束时再次记录了会话的内容。在开发模式csrf_token
的会话内容保持跨越多个请求,例如不变,
<KVSession {'csrf_token': '79918c1e3191e4d4fe89a9499f576404a18be8e4'}>
形式的内容在这两种情况下正确地传送,例如,
ImmutableMultiDict([('csrf_token', u'1403778775.86##34f1447f1b8c78808f4e71f2ff037bcd1df41dcd'),
('time', u'8'), ('submit', u'Go'), ('dose', u'Low')])
当我通过Apache运行我的应用程序,会话内容将随每个请求一起重置。在视图开始时会话内容为空:
<KVSession {}>
然后每次都会设置一个新的令牌,导致不匹配。目前,我__init__.py
模块如下所示:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from simplekv.memory import DictStore
from flaskext.kvsession import KVSessionExtension
app = Flask(__name__)
app.config.from_object("myapp.config.Config")
db = SQLAlchemy(app)
store = DictStore()
KVSessionExtension(store, app)
from . import views
我删除了KVSession
陈述,但这并没有改变的问题。所以我认为服务器端会话不是罪魁祸首。
是的,我已经在配置中将SECRET_KEY
设置为os.urandom(128)
。
我httpd.conf
相关的(我认为)节:
Listen url.com:8090
<VirtualHost url.com:8090>
# --- Configure VirtualHost ---
LogLevel debug
ServerName url.com
DocumentRoot /path/to/flaskapp/htdocs
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /path/to/flaskapp/htdocs/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
</Directory>
# --- Configure WSGI Listening App(s) ---
WSGIDaemonProcess mysite user=me group=us processes=2 threads=10
WSGIScriptAlias//path/to/flaskapp/wsgi/wsgi.py
<Directory /path/to/flaskapp/wsgi/>
WSGIProcessGroup mysite
WSGIApplicationGroup %{GLOBAL}
WSGIScriptReloading On
Require all granted
</Directory>
# --- Configure Static Files ---
Alias /static/ /path/to/flaskapp/htdocs/static/
Alias /tmp/ /path/to/flaskapp/htdocs/tmp/
</VirtualHost>
有谁知道关于Apache设置或瓶的相互作用mod_wsgi的,可能导致会议不能请求之间仍然存在?
你的mod_wsgi配置是什么样的? –
@SeanVieira我加了'httpd.conf'的一部分。我只加载'mod_wsgi'模块('LoadModule wsgi_module lib/httpd/mod_wsgi.so'),但没有改变它的配置。 – Midnighter
我的猜测是你每次处理两个不同的进程,因为当你的代码被加载时,你使用'os.urandom'创建你的密钥,这会导致每个进程都有一个* * *密码,这是不你想要什么。要确认,请尝试使用硬编码的密钥,并查看是否解决了问题。如果是这样,您可以在部署时生成一个密钥,并将其存储在磁盘或内存中,并引用您的生产密钥。 [查看更多](https://code.google.com/p/modwsgi/wiki/ProcessesAndThreading#Sharing_Of_Global_Data) –