Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将csrf验证添加到金字塔中?_Python_Pyramid - Fatal编程技术网

Python 如何将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

我将为每个post和xhr请求传递一个csrf_令牌,并希望根据会话csrf令牌验证该令牌。如果他们不匹配,我会投401

我使用了金字塔中的NewResponse订阅者来检查请求,并根据会话中的令牌验证请求参数中的csrf令牌。验证可以工作,但它仍然调用视图,因此它不能正常工作

对正确的方法有什么建议吗

@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事件处理程序中引发异常也会起作用。谢谢,这很有意义。