I have previous experience in Django
. If add line {csrf_token}
in Django
templates then Django
handles the functionalities of csrf_token
. But when I am trying to develop an API using Django REST Framework
then I get stuck. How can I add and handle functionalities like csrf_token
in API
(back end, developed using Django REST Framework
) and React Native/React JS
(front end) like Django templates?
The first step is to get CSRF token which can be retrieved from the Django csrftoken cookie. var csrftoken = getCookie('csrftoken'); Next you can use this csrf token when sending a request with fetch() by assigning the retrieved token to the X-CSRFToken header.
Let's say you have a NodeJS and Express back end that interacts with your React client. You can install a library called csurf that's used to generate CSRF tokens, and you can send them to your client through an endpoint. Now you need to add the following endpoint. const csrfProtection = csrf({ cookie: true }); app.
We also established that when using React and Django together, React serves as the frontend (client-side framework), that handles the UI and getting & setting data via requests to the Django backend, which is an API built using the Django REST framework (DRF).
The CSRF token is like an alphanumeric code or random secret value that's peculiar to that particular site. Hence, no other site has the same code. In Django, the token is set by CsrfViewMiddleware in the settings.py file. A hidden form field with a csrfmiddlewaretoken field is present in all outgoing requests.
The first step is to get CSRF token which can be retrieved from the Django csrftoken cookie.
Now from the Django docs you can find out how to get the csrf token from the cookie by using this simple JavaScript function:
function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }
Now, you can retrieve the CSRF token by calling the getCookie('csrftoken')
function
var csrftoken = getCookie('csrftoken');
Next you can use this csrf token when sending a request with fetch() by assigning the retrieved token to the X-CSRFToken header.
fetch(url, { credentials: 'include', method: 'POST', mode: 'same-origin', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, body: {} }) }
Rendering the CSRF Token in React Forms:
If you are using React to render forms instead of Django templates you also need to render the csrf token because the Django tag { % csrf_token % }
is not available at the client side so you need to create a higher order component that retrieves the token using the getCookie()
function and render it in any form.
Lets add some line in csrftoken.js
file.
import React from 'react'; var csrftoken = getCookie('csrftoken'); const CSRFToken = () => { return ( <input type="hidden" name="csrfmiddlewaretoken" value={csrftoken} /> ); }; export default CSRFToken;
Then you can simply import it and call it inside your form
import React, { Component , PropTypes} from 'react'; import CSRFToken from './csrftoken'; class aForm extends Component { render() { return ( <form action="/endpoint" method="post"> <CSRFToken /> <button type="submit">Send</button> </form> ); } } export default aForm;
The Django CSRF Cookie
React renders components dynamically that's why Django might not be able to set a CSRF token cookie if you are rendering your form with React. This how Django docs says about that:
If your view is not rendering a template containing the csrftoken template tag, Django might not set the CSRF token cookie. This is common in cases where forms are dynamically added to the page. To address this case, Django provides a view decorator which forces setting of the cookie: ensurecsrf_cookie().
To solve this issue Django provides the ensurecsrfcookie decorator that you need to add to your view function. For example:
from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def myview(request):
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With