Python 如何将csrf验证添加到金字塔中?
我将为每个post和xhr请求传递一个csrf_令牌,并希望根据会话csrf令牌验证该令牌。如果他们不匹配,我会投401 我使用了金字塔中的NewResponse订阅者来检查请求,并根据会话中的令牌验证请求参数中的csrf令牌。验证可以工作,但它仍然调用视图,因此它不能正常工作 对正确的方法有什么建议吗Python 如何将csrf验证添加到金字塔中?,python,pyramid,Python,Pyramid,我将为每个post和xhr请求传递一个csrf_令牌,并希望根据会话csrf令牌验证该令牌。如果他们不匹配,我会投401 我使用了金字塔中的NewResponse订阅者来检查请求,并根据会话中的令牌验证请求参数中的csrf令牌。验证可以工作,但它仍然调用视图,因此它不能正常工作 对正确的方法有什么建议吗 @subscriber(NewResponse) def new_response(event): """Check the csrf_token if the user is auth
@subscriber(NewResponse)
def new_response(event):
"""Check the csrf_token if the user is authenticated and the
request is a post or xhr req.
"""
request = event.request
response = event.response
user = getattr(request, 'user', None)
# For now all xhr request are csrf protected.
if (user and user.is_authenticated()) and \
(request.method == "POST" or request.is_xhr) and \
(not request.params.get('csrf_token') or \
request.params.get('csrf_token') != unicode(request.session.get_csrf_token())):
response.status = '401 Unauthorized'
response.app_iter = []
调用视图后,将调用
NewResponse
订阅服务器
您希望使用先前调用的事件,例如NewRequest
或ContextFound
。在Pyramid 1.0中,您需要使用ContextFound
来正确处理事情,因为您不能在NewRequest
事件中引发异常(这在1.1中已修复)
使用ContextFound
事件执行此操作的方法是为HTTPException对象注册异常视图,如下所示:
config.add_view(lambda ctx, req: ctx, 'pyramid.httpexceptions.HTTPException')
基本上,当您引发异常时,它会将异常作为响应对象返回,这对于HTTPException对象非常有效,HTTPException对象是有效的金字塔response
对象
然后,您可以注册事件并处理CSRF验证:
@subscriber(ContextFound)
def csrf_validation_event(event):
request = event.request
user = getattr(request, 'user', None)
csrf = request.params.get('csrf_token')
if (request.method == 'POST' or request.is_xhr) and \
(user and user.is_authenticated()) and \
(csrf != unicode(request.session.get_csrf_token())):
raise HTTPUnauthorized
金字塔包含了它的内部结构,这可能是一个更好的选择
考虑到会话存储的CSRF令牌,这将导致以下配置:
from pyramid.csrf import SessionCSRFStoragePolicy
def includeme(config):
# ...
config.set_csrf_storage_policy(SessionCSRFStoragePolicy())
config.set_default_csrf_options(require_csrf=True)
我认为您希望使用pyramid.events.ContextFound事件而不是pyramid.events.NewResponse;在这里,事件上没有响应对象,而是在ContextFound的事件订阅服务器中使用“raise pyramid.exceptions.Forbidden”,而不是修改响应。请注意,在1.1(昨天发布的a1)中,从NewRequest事件处理程序中引发异常也会起作用。谢谢,这很有意义。