Validating CSRF Validation Using Django Rest Framework

I am using Django Rest Framework 3 and want to check the CSRF check.

First I initialize DRF APIClient:

client = APIClient(enforce_csrf_checks=True)

Then I set a password for the user, so I can log in and get a session:

superuser.set_password('1234')
superuser.save()
client.login(email=superuser.email, password='1234')

Now we need the CSRF token. To do this, I simply create a request and extract the token from the cookies.

response = client.request()
csrftoken = client.cookies['csrftoken'].value

When checking the code, this seems to work, I am returning a valid CSRF token. Then I execute a POST request by passing a parameter csrfmiddlewartoken:

data = {'name': 'My fancy test report', 'csrfmiddlewaretoken': csrftoken}
response = client.post(API_BASE + '/reports', data=data, format='json')
assert response.status_code == status.HTTP_201_CREATED, response.content

The problem is that this fails:

tests/api/test_api.py:156: in test_csrf_success
    assert response.status_code == status.HTTP_201_CREATED, response.content
E   AssertionError: {"detail":"CSRF Failed: CSRF token missing or incorrect."}
E   assert 403 == 201
E    +  where 403 = <rest_framework.response.Response object at 0x7f7bd6453bd0>.status_code
E    +  and   201 = status.HTTP_201_CREATED

What is the correct way to verify CSRF validation using DRF?

+4
source share
1 answer

EDIT

, , :

Django CSRF , , csrf_token. , , csrf, , , ensure_csrf_cookie.

csrf , , :

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def token_security(request):
    return HttpResponse()  # json or whatever

, , POST CSRF CSRF-, GET , cookie, POST.

:


( User, ):

class TestLoginApi(APITestCase):
    def setUp(self):
        self.client = APIClient(enforce_csrf_checks=True)
        self.path = reverse("registration:login")
        self.user = UserFactory()

    def tearDown(self):
        self.client.logout()

    def _get_token(self, url, data):
        resp = self.client.get(url)
        data['csrfmiddlewaretoken'] = resp.cookies['csrftoken'].value
        return data

   def test_login(self):
        data = {'username': self.user.username,
                'password': PASSWORD}
        data = self._get_token(self.path, data)

        # This should log us in.
        # The client should re-use its cookies, but if we're using the
        # `requests` library or something, we'd have to re-use cookies manually.
        resp = self.client.post(self.path, data=data)
        self.assertEqual(resp.status_code, 200)
        etc.

, , cookie GET, Django (. ), , POST {% csrf_token %}.

, ( DRF view.py):

from django.utils.decorators import method_decorator
from django.views.decorators.csrf import ensure_csrf_cookie

    @method_decorator(ensure_csrf_cookie)
    def get(self, request, *args, **kwargs):
        return SomeJson...

, Django Rest Framework , POST csrf ( , ):

from django.views.decorators.csrf import csrf_protect

    @method_decorator(csrf_protect)
    def post(self, request, *args, **kwargs):
        return SomeJson...
+6

All Articles