在 Pyramid 中使用多个 gunicorn worker 检查 CSRF
Checking CSRF with multiple gunicorn workers in Pyramid
我正在为我的网络应用程序使用 Pyramids,它需要对每个请求进行 csrf 检查。在 ajax-calls 期间,每个请求的 csrf-token 都设置到 header 中。 1 thread with 1 worker 一切正常,但是一旦我启用多个 worker,worker 2 就不知道来自 worker 1 的令牌. 他们如何分享 csrf 代币?
问候
production.ini 对于 gunicorn:
[server:main] # GUNICORN
use = egg:gunicorn#main
bind = unix:/tmp/gunicorn.sock
workers = 2
threads = 1
preload = true
reload = true
accesslog = gunicorn_access.log
loglevel = info
在金字塔中我只设置了:
config.set_default_csrf_options(require_csrf=True)
我的 HTML-skeletion 有:
<input type="hidden" id="hidden_csrf_token" name="csrf_token" value="${request.session.get_csrf_token()}">
每个 ajax-request:
var csrf_token = $('#' + hiddenCSRFTokenId).val();
...
headers: {'X-CSRF-Token': csrf_token}
编辑:我正在使用默认 session工厂
session_factory = session_factory_from_settings(settings)
...
config.set_session_factory(session_factory)
因此我想使用烧杯:
# Beaker cache
beaker.cache.regions = short_term, long_term
beaker.cache.type = memory
beaker.cache.short_term.expire = 3600
beaker.cache.long_term.expire = 86400
# Beaker sessions
beaker.session.type = redis
beaker.session.data_dir = %(here)s/data/sessions/data
beaker.session.lock_dir = %(here)s/data/sessions/lock
beaker.session.autor = true
#beaker.session.type = memory
beaker.session.key = dbas_prototyp
beaker.session.secret = ...
beaker.session.cookie_max_age = 3600
beaker.session.timeout = 3600
beaker.session.cookie_expires = true
beaker.session.url:127.0.0.1:4284
我在设置烧杯时是否漏掉了什么?
beaker.cache.type=memory
是会话数据的进程内内存存储(我的猜测)。你们是 运行 两个不同的进程,自然他们看不到彼此的内存空间。
使用不同的 Beaker 后端或类似 pyramid_redis_session 跨进程(和服务器)共享会话数据。
我认为我找到了第一个可行的解决方案。我正在使用带有简单外部数据库的烧杯,例如:
session.url = postgresql+psycopg2://user:password&@localhost:port/database?client_encoding=utf8
# Beaker cache
beaker.cache.regions = short_term, long_term
beaker.cache.type = ext:database
beaker.cache.short_term.expire = 3600
beaker.cache.long_term.expire = 86400
beaker.cache.extend_existing = True
beaker.cache.table_name = beaker_cache
beaker.session.type = ext:database
beaker.session.key = yyy
beaker.session.secret = xxx
beaker.session.cookie_max_age = 3600
beaker.session.timeout = 3600
beaker.session.cookie_expires = true
beaker.session.table_name = beaker_session
我会 post 在解决一些其他问题后,使用 Redis 解决方案。
我正在为我的网络应用程序使用 Pyramids,它需要对每个请求进行 csrf 检查。在 ajax-calls 期间,每个请求的 csrf-token 都设置到 header 中。 1 thread with 1 worker 一切正常,但是一旦我启用多个 worker,worker 2 就不知道来自 worker 1 的令牌. 他们如何分享 csrf 代币?
问候
production.ini 对于 gunicorn:
[server:main] # GUNICORN
use = egg:gunicorn#main
bind = unix:/tmp/gunicorn.sock
workers = 2
threads = 1
preload = true
reload = true
accesslog = gunicorn_access.log
loglevel = info
在金字塔中我只设置了:
config.set_default_csrf_options(require_csrf=True)
我的 HTML-skeletion 有:
<input type="hidden" id="hidden_csrf_token" name="csrf_token" value="${request.session.get_csrf_token()}">
每个 ajax-request:
var csrf_token = $('#' + hiddenCSRFTokenId).val();
...
headers: {'X-CSRF-Token': csrf_token}
编辑:我正在使用默认 session工厂
session_factory = session_factory_from_settings(settings)
...
config.set_session_factory(session_factory)
因此我想使用烧杯:
# Beaker cache
beaker.cache.regions = short_term, long_term
beaker.cache.type = memory
beaker.cache.short_term.expire = 3600
beaker.cache.long_term.expire = 86400
# Beaker sessions
beaker.session.type = redis
beaker.session.data_dir = %(here)s/data/sessions/data
beaker.session.lock_dir = %(here)s/data/sessions/lock
beaker.session.autor = true
#beaker.session.type = memory
beaker.session.key = dbas_prototyp
beaker.session.secret = ...
beaker.session.cookie_max_age = 3600
beaker.session.timeout = 3600
beaker.session.cookie_expires = true
beaker.session.url:127.0.0.1:4284
我在设置烧杯时是否漏掉了什么?
beaker.cache.type=memory
是会话数据的进程内内存存储(我的猜测)。你们是 运行 两个不同的进程,自然他们看不到彼此的内存空间。
使用不同的 Beaker 后端或类似 pyramid_redis_session 跨进程(和服务器)共享会话数据。
我认为我找到了第一个可行的解决方案。我正在使用带有简单外部数据库的烧杯,例如:
session.url = postgresql+psycopg2://user:password&@localhost:port/database?client_encoding=utf8
# Beaker cache
beaker.cache.regions = short_term, long_term
beaker.cache.type = ext:database
beaker.cache.short_term.expire = 3600
beaker.cache.long_term.expire = 86400
beaker.cache.extend_existing = True
beaker.cache.table_name = beaker_cache
beaker.session.type = ext:database
beaker.session.key = yyy
beaker.session.secret = xxx
beaker.session.cookie_max_age = 3600
beaker.session.timeout = 3600
beaker.session.cookie_expires = true
beaker.session.table_name = beaker_session
我会 post 在解决一些其他问题后,使用 Redis 解决方案。