1

I am using Django Rest Framework and React. When I run the react app on "localhost:3000", every post request is accepted and worked fine. But After I build the react app with "npm run build". Then, all POST requests are being Forbidden(403) on "localhost:8000". but still, everything is fine on "localhost:3000"

pplonski
  • 5,023
  • 1
  • 30
  • 34

2 Answers2

0

Django has cross-site request forgery (CSRF) protection. In each form it uses a small extra element that contains a csrf token, and then validates this.

You can extract the csrf token with a JavaScript function specified in the Django documentation:

function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
const csrftoken = getCookie('csrftoken');

then you can make a fetch with:

fetch(url, {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json',
      'X-CSRFToken': csrftoken
    },
    body: {
        // …
    }
})
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • It worked for me. But I don't understand why CSRF TokenAuthentication is needed in "localhost:8000" but not required in "localhost:3000". There are no CSRF Cookies in "localhost:3000". – Nirajan Bekoju Nov 22 '20 at 01:44
0

There can be many reasons:

# update backend/server/server/settings.py
# ...
INSTALLED_APPS = [
    #...
    'corsheaders', # add it here
    #...
]

# define which origins are allowed
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
    "http://127.0.0.1:3000"
]

# add to middleware
MIDDLEWARE = [
    #...
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    #...
]
  • Please check ALLOWED_HOSTS in settings.py
  • Please try to run Django server with DEBUG=True and check more info about the request, you can check it in developer tools in web browser
  • Please check at what address your requests are send? I'm using different server address for development and production:
import axios from "axios";
if (window.location.origin === "http://localhost:3000") {
  axios.defaults.baseURL = "http://127.0.0.1:8000";
} else {
  axios.defaults.baseURL = window.location.origin;
}

  • As Willem Van Onsem wrote, it can be the issue with CSRF, but CSRF is enabled by default only for session based authentication (what authentication are you using?)

Please take a look at the following articles:

pplonski
  • 5,023
  • 1
  • 30
  • 34