Learn how to deal with the Django 403 Forbidden Error: CSRF Verification failed

How to handle Postman and Django 403 Forbidden Error: CSRF verification failed

After implementing a new project with Django that should allow to me to send some long text to the server, then use the KeyBERT library to extract automatically the Keywords from the sent text and finally send me a JSON response with the result. Once I deployed the project to test it using Postman, I found this error when trying to send directly a POST request to my view in Django using Postman.

In this article, I will explain to you 2 possible ways to circumvent this exception when sending requests through Postman to your Django project.

A. Disable CSRF protection for as specific view

Disabling the CSRF protection of a real project or something that really requires it is in no one's head. You shouldn't definitively do this unless you know what you're doing (you understand totally how a CSRF attack and how could it be a problem to your application if you allow form submission without CSRF protection). Some cases where it could be feasible to use this approach:

  • A local API that you're testing locally only.
  • A public API that's designed to be accessible for anyone but somehow you trust all the possible requests (e.g your API is only accessible for specific IPs like the IP of another server that requests information from this endpoint and it has already CSRF protection with another language like PHP).

Otherwise, don't do it. In my case, I designed a basic API that runs a machine learning library and should return the result of it as response, however the API doesn't need any user implementation as it's mean to be used only for me. This approach consists of disabling the CSRF protection of a specific route:

# views.py
from django.http import JsonResponse

# 1. Import the csrf_exempt decorator
from django.views.decorators.csrf import csrf_exempt

# 2. Exempt the view from CSRF checks
def extract_keywords(request):
    text = request.POST.get('text')
    return JsonResponse(text)

The decorator will disable the CSRF checks for the route, in this case the extract_keywords method of the view. If you send the POST request to the same route again with Postman, it should succeed this time.

B. Auto-set X-CSRFToken header in Postman

The second option will work only if you are facing the following situation. If you have a Django project working properly let's say in the following URL http://localhost:8080/my-form and it answers to GET and POST requests. Your project works properly, when you access the Form address through the browser through a GET request, the form will be rendered so the user can easily submit the data and when it's submitted through a POST request, the request succeeds in the browser as expected. The problem with Postman appears when it works in the browser, but if you try to simulate the POST request to the same address using Postman, the mentioned exception will appear.

As previously mentioned, Django has inbuilt CSRF protection. The only mechanism that you have to trigger an AJAX request when this protection is enabled is to add the X-CSRFToken header to your request (which should contain a valid CSRF token to validate in the server). You can obtain this token first triggering a GET request to the endpoint to obtain the token and then use a Postman test script to manipulate the subsequent request with JavaScript adding the required header.

To accomplish this, open the Tests tab of your postman request and add the following test code:

var xsrfCookie = postman.getResponseCookie("csrftoken");
postman.setEnvironmentVariable('csrftoken', xsrfCookie.value);

This test JavaScript is executed after the response is received. Once it's there, run the GET request:

Postman GET request Django

What we did with the previous code is basically extracting the csrftoken of the form obtained with the GET request and it's now going to be used in the subsequent POST request to validate the form. This token will be stored as an environment variable namely csrftoken, so we can easily add it to the new POST request as a new header:

Headers CSRF Token

After declaring the header, simply run the POST request and it should now succeed:

POSTMAN csrftoken Post

Happy coding ❤️!

Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.