Reputation: 33901
I've got a test where I'm checking some authentication behavior. In this test I need to explicitly check CSRF behavior, so I'm using a test client enforce_csrf_checks
set to True
:
self.csrf_client = Client(enforce_csrf_checks=True)
My question is, what's the simplest way for me to manually get a CSRF token to send with a POST request I'm going to make to that client?
Is the best option to define a custom test view that returns csrf(request)
, make a request to that view, extract the CSRF token and then use it in the POST request, or is there some easier way I can get a CSRF token to use?
Upvotes: 11
Views: 8816
Reputation: 917
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.
Upvotes: 1
Reputation: 136
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
Upvotes: 16
Reputation: 42805
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?
Upvotes: 1