[Solved]-Manually get a CSRF token when testing

15๐Ÿ‘

โœ…

I know this is an old question, but I stumbled across this while searching for a solution and now I wanted to share my solution in case anyone else has a problem with this.

The CSRF token is indeed stored in the cookie after you login and to access it I had to do the following:

self.client = Client(enforce_csrf_checks=True)
self.client.login(username='temporary', password='temporary')
self.client.get("/url_to_the_form/")
csrf_token = self.client.cookies['csrftoken'].value
๐Ÿ‘คDaniel Karlsson

1๐Ÿ‘

The CSRF token should be getting sent to the client as a cookie (named "csrftoken"). The client is expected to send that cookie back with further requests. Could your Client copy the cookie to where you need it?

๐Ÿ‘คMike DeSimone

0๐Ÿ‘

Iโ€™m nine years late to the party, but I stumbled upon this question when I was trying to figure out how to test a login API endpoint using Django Rest Framework for which I enabled CSRF protection. Hopefully this helps anyone else in a similar spot.

The solution I arrived at was creating a csrf-token endpoint:

# csrf_token.py

from django.middleware import csrf
from rest_framework.views import APIView
from rest_framework import status
from rest_framework.response import Response


class CsrfTokenView(APIView):
    def get(self, request):
        csrf_token = csrf.get_token(request)

        return Response(
            data={'csrf_token': csrf_token},
            status=status.HTTP_200_OK
        )
# set up for test class for login endpoint

def setUp(self):
    self.client = APIClient(enforce_csrf_checks=True)
    csrf_response = self.client.get(reverse('csrf-token'))
    self.csrf_token = csrf_response.data['csrf_token']
    self.client.credentials(HTTP_X_CSRFTOKEN=self.csrf_token)

Adding the self.client.credentials piece ensures the subsequent tests against the login endpoint with CSRF checks enforced pass as expected.

๐Ÿ‘คDerek

Leave a comment