在Django Rest Framework中测试CSRF保护视图

时间:2020-10-10 22:44:32

标签: django django-rest-framework

在测试需要身份验证的APIView时,我遇到了麻烦。我想测试CSRF和身份验证+权限是否均按预期执行。

我的设置的一些信息:

  • 我的观点是实现rest_framework.views.APIView函数的Django Rest框架post
  • 默认身份验证类为SessionAuthentication
  • 默认权限类别为IsAuthenticated
  • 测试用例使用APIClient发出请求

在使用APIClient初始化enforce_csrf_checks=True时,对于需要认证的视图(使用IsAuthenticated权限类),我似乎仍然无法获得期望的响应。

对于未经身份验证的视图,我可以测试CSRF保护,没问题。

相关视图:

@method_decorator(csrf_protect)
def post(self, request, format=None):
    """
    Create a new user.
    """
    serializer = UserSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

测试代码:

client = APIClient()
response = client.post(url, data)
# Success!

client = APIClient(enforce_csrf_checks=True)
response = client.post(url, data)
# 403 FORBIDDEN

对于经过身份验证的视图,情况会变得很奇怪(此视图使用IsAuthenticated权限:

def get(self, request, format=None):
    """
    Get request user.
    """
    user = User.objects.get(pk=request.user.id)
    serializer = UserSerializer(user)
    return Response(serializer.data, status=status.HTTP_200_OK)

测试代码:

self.client = APIClient(enforce_csrf_checks=True)
self.client.login(email='t@t.se', password='pw')

self.client.get(url)
# Succeeds, even though it should not. No CSRF HTTP header is set.

客户端初始化参数enforce_csrf_checks似乎没有任何作用,或者我不知道应如何使用它。

1 个答案:

答案 0 :(得分:0)

正如Clepsyd在this comment中指出的那样,CSRF并不旨在保护GET方法视图免受来自被劫持会话的请求。事实证明,我只有“问题” CSRF保护GET视图,而没有别的。由于不打算在GET视图上使用CSRF保护,因此我的问题无关紧要,我将需要寻找另一种保护GET视图的方法以防止数据泄漏。