apache - 由于 session 重置,Apache Flask 中的 CSRF token 不匹配

标签 apache python-2.7 flask csrf flask-wtforms

我有一个在开发环境中完美运行的 CSRF 保护表单示例(Flask 使用 app.run 运行服务器本身)但是当我通过 mod_wsgi 运行应用程序时失败在 Apache 。我使用的版本是:

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在 View 的开头和 session 的内容再次在 View 的结尾。在开发模式下csrf_token的内容在 session 中在多个请求中保持不变,例如,
<KVSession {'csrf_token': '79918c1e3191e4d4fe89a9499f576404a18be8e4'}>

在这两种情况下,表格的内容都会正确传输,例如,
ImmutableMultiDict([('csrf_token', u'1403778775.86##34f1447f1b8c78808f4e71f2ff037bcd1df41dcd'),
('time', u'8'), ('submit', u'Go'), ('dose', u'Low')])

当我通过 Apache 运行我的应用程序时,每次请求都会重置 session 内容。在 View 的开头, session 内容为空:
<KVSession {}>

然后每次都会设置一个新的 token ,这会导致不匹配。目前,我的__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声明并没有改变问题。所以我认为服务器端 session 不是罪魁祸首。

是的,我设置了 SECRET_KEYos.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 与 Flask 交互可能导致 session 在请求之间不持久?

最佳答案

这里发生的是您使用 Flask-KVSession 存储 session 。 ,并提供基于内存的 DictStore作为存储:

from simplekv.memory import DictStore

store = DictStore()
KVSessionExtension(store, app)

根本原因

在单线程环境中,这将起作用。但是,当多个进程起作用时,它们不会共享相同的内存,并且 DictStore 的多个实例被创建,每个进程一个。结果,当两个后续请求由两个不同的进程提供服务时,第一个请求将无法将 session 更改传递给下一个请求。

或者,甚至更短:两个进程 = 两个 CSRF token 。不好。

解决方案

使用持久存储。这就是我使用的:
def configure_session(app):
    with app.app_context():
        if config['other']['local_debug']:
            store = simplekv.memory.DictStore()
        else:
            store = simplekv.db.sql.SQLAlchemyStore(engine, metadata, 'sessions')

        # Attach session store
        flask_kvsession.KVSessionExtension(store, app)

关于apache - 由于 session 重置,Apache Flask 中的 CSRF token 不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24427274/

相关文章:

python - 将列表与列表列表合并

python - Flask-Blogging 错误表已定义

python - 如何在 Flask 上动态更新我的 Python 图表?

Python,Flask - 如何构建一个安静的Web服务方法来管理上传的文件?

apache - FQDN 上的 SSL 与 IP

apache - 引用: mod_rewrite, URL重写和 "pretty links"解释

java - ActiveMQ - 控制一次消耗多少消息。

java - 通过 Apache Drill 访问 Postgres 中的复合数据

python - 从 Web 运行 Python 脚本

python - 更改字符串列表中的字符串