varugasu
varugasu

Reputation: 55

Django backend, React frontend and CSRF Post

In my cenario I am using a form in my react frontend (http://localhost:3000/submit) to post to my url http://localhost:8000/api/submit/

However, I have received this response:

"detail": "CSRF Failed: CSRF token missing or incorrect."

My class view is something like that:

from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser

class Submit(APIView):
    parser_classes = (MultiPartParser, FormParser)
    def post(self, request, *args, **kwargs):
        #custom post

I have two questions:

  1. How do I decorate dispatch() to exempt csrf?
  2. How can I provide CSRF to my frontend?

**

SOLUTION by Risadinha:

**

import cookie from "react-cookies";

...

<input
 type="hidden"
 value={cookie.load("csrftoken")}
 name="csrfmiddlewaretoken"
/>

Upvotes: 4

Views: 5426

Answers (2)

Risadinha
Risadinha

Reputation: 16666

You need to set both the cookie and the header to the CSRF token as transmitted during the initial call wich loads the react page.

Basically you need to read the value of the cookie "csrftoken" as transmitted from the Django server and set that as the value of the header "X-CSRFTOKEN" for all the post AJAX requests in your react app. Best done generally (index.js for example).

Example using axios (we are using graphql) client in React:

import axios from "axios";
import cookie from "react-cookies";

axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";

your_client.setHeaders({"X-CSRFTOKEN": cookie.load("csrftoken")});

Without ajax, add the cookie's value to the form like this - if you cannot use the template tag {% csrf_token %} (in a react form):

<input type="hidden" name="csrfmiddlewaretoken" value="{value-of-the-cookie}" /> 

The documentation: https://docs.djangoproject.com/en/3.1/ref/csrf/

Upvotes: 3

nbwoodward
nbwoodward

Reputation: 3156

This seems a bit hacky but you can get the csrf token in a view with the django.middleware.csrf.get_token() method. So I would make a view like this:

from django.http import JsonResponse

def get_csrf(request):
    csrf_token = django.middleware.csrf.get_token()
    return JsonResponse({'csrf_token':csrf_token})

Of course you want to protect this request so anyone can't grab the token. Which seems to defeat the purpose of it anyway...

Upvotes: 0

Related Questions