Django csrf_exempt不使用SessionAuthentication

时间:2017-01-14 23:31:11

标签: python django django-rest-framework django-csrf

我正在使用Django Rest Framework构建一个带有用户注册/登录的webapp。 我试图免除用户注册视图需要CSRF令牌。这就是我现在的看法:

class UserSignUpView(generics.CreateAPIView):
    permission_classes = [] # FIXME: doesn't seem to be working
    serializer_class = UserSerializer

    @method_decorator(csrf_exempt)
    def post(self, request, *args, **kwargs):
        super().post(self, request, *args, **kwargs)

    def get_permissions(self):
        if self.request.method == 'POST':
            return (permissions.AllowAny(), TokenHasReadWriteScope())
        return False

我的settings.py看起来像这样:

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': [
       'rest_framework.permissions.AllowAny',
    ]
}

我仍然在后端输出Forbidden (CSRF cookie not set.): /users/和前端经典CSRF verification failed. Request aborted.

为什么这不起作用?它是否与我从未手动设置CSRF cookie的事实有关?

1 个答案:

答案 0 :(得分:0)

Django REST框架已经阻止CSRFViewMiddleware在任何csrf_exempt上使用APIView执行CSRF检查。相反,它在使用SessionAuthentication成功验证用户时显式调用CSRF检查。你不能绕过这个检查,也不应该。常规Django视图可能不依赖于会话,在这种情况下无法进行CSRF攻击,您可以使用csrf_exempt来指示此情况。当您使用SessionAuthentication时, 容易受到CSRF攻击,您需要进行检查以防止攻击。在这种情况下绕过检查通常会让您遇到漏洞,这就是DRF不允许您禁用检查的原因。

你基本上有两种方法可以解决这个问题:

  • 确保用户未SessionAuthentication成功通过身份验证。
  • 确保已设置Cookie,并在X-CsrfToken请求标头中发送令牌。