-1

I've been trying for hours to send a POST request to an endpoint in my Django application from my separated VueJS frontend using Axios. The problem with my code is that whatever i try i will always get Forbidden (CSRF cookie not set.), and i can't use @crsf_exempt.

I tried every possible solution i found, from changing headers names in my Axios request to setting CSRF_COOKIE_SECURE to False, nothing seems to solve this problem.

Here is my request:

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 = 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;
          }
      }
  }
  console.log(cookieValue)
  return cookieValue;
}

function req(){

  this.csrf_token = getCookie('csrftoken')

  axios({
    method: 'post',
    url: 'http://127.0.0.1:8000/backend/testreq/',

    data: {
      //Some data here
    },

    headers: {'Content-Type': 'application/json', 'X-CSRFToken': this.csrf_ftoken }
  }).then(function (response) {
    console.log(response)
  }).catch(function (error) {
    console.log(error)
  });

},

The token is being sent but the outcome is always the same. The Django app is using Django-Rest-Framework too, i don't know if that's the problem.

Here is some of my settings.py (for development):

CORS_ORIGIN_ALLOW_ALL = True  

CORS_ALLOW_CREDENTIALS = True

CORS_ALLOW_HEADERS = list(default_headers) + [
    'xsrfheadername',
    'xsrfcookiename',
    'content-type',
    'csrftoken',
    'x-csrftoken',
    'X-CSRFTOKEN',
]

CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_WHITELIST = [
    "http://localhost:8080",
    "http://127.0.0.1:8080",
    "http://localhost:8000",
    "http://127.0.0.1:8000",
]

CORS_ALLOWED_ORIGINS = [
    "http://localhost:8080",
    "http://127.0.0.1:8080",
    "http://localhost:8000",
    "http://127.0.0.1:8000",
]
CSRF_TRUSTED_ORIGINS = [
    "http://localhost:8080",
    "http://127.0.0.1:8080",
    "http://localhost:8000",
    "http://127.0.0.1:8000",
]

SESSION_COOKIE_SAMESITE = None
CSRF_COOKIE_SAMESITE = None

CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
SESSION_COOKIE_SECURE = False

I don't know what else can i try to solve this problem, any advice is appreciated

Jack022
  • 867
  • 6
  • 30
  • 91

2 Answers2

0

The Default Authentication Scheme in Django Rest Framework is

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

Session Authentication requires a CSRF Token when you make POST requests unless exempted using @csrf_exempt

CSRF_COOKIE_SECURE in Django only ensures that CSRF Tokens are sent via HTTPS

To Fix Your Issue, you can change DEFAULT_AUTHENTICATION_CLASSES from the default to

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ]
}

Once you switch to TokenAuthentication you'll have to exchange the user's credentials for an Auth token and use that Token For Subsequent requests

Django Rest Framework's guide on Token Authentication

You can also take a look at this SO answer here to use @csrf_exempt on class based views

salami
  • 26
  • 3
  • Thank you a lot, but unfortunately Session Authentication is required on this project, i thought of using token but i would rather go with Session for now – Jack022 Mar 25 '21 at 18:09
  • You may want to take a look at this [answer](https://stackoverflow.com/a/19008548/14559369) incase you have any of the options turned on. – salami Mar 26 '21 at 06:57
-1

I suppose it's a problem caused by 'cross-domain', you cannot set cookie or store it in browser generated by backend localhost:8000 through frontend localhost:8080. If you want to store or modify cookie you can only access localhost:8000.

You can use Nginx as reverse proxy to solve the problem, Here is the video for details https://youtube.com/watch?v=VeDms9GPaLw

Asark
  • 1
  • 4
    Please don't say "You can do x" and then post a link to a video that isn't in English to explain how to do x. – David Buck Nov 06 '21 at 20:05