title: Django CSRF cookie not set: using Ajax Cross site
body: <p>I have two parts of my code first is a <strong>frontend (no framework/library)</strong> running on <code>localhost:3000</code> via simple <code>python HTTP server</code> and a <code>Django server</code> running on <code>localhost:8080</code>, what's happening in here is <strong>the frontend is making a cross-site POST request to Django server</strong> but its been getting a <strong>Forbidden (CSRF cookie not set.)</strong> error. I know this problem has been asked about so many times but I don't seem to find a solution.</p>
  <p>I don't have any experience requesting a <strong>POST</strong> call in Django like this, not using <strong>DRF</strong> but <strong>endpoints</strong> of our own.</p>
  <h2><strong>The Problem Code:</strong></h2>
  <p>firstly the <strong>frontend</strong> shall make a get request for a <strong>csrf token</strong> to <code>/api/csrf/</code></p>
  <h3>views.py:</h3>
  <pre><code>def get_csrf(request):
      # print(get_token(request))
      return JsonResponse({
          'detail': 'CSRF cookie set',
          'X-CSRFToken': get_token(request)
          })
  </code></pre>
  <p>After getting the value, the token is assigned to the <strong>cookie</strong> and a <strong>hidden element</strong> via</p>
  <h3>main.js:</h3>
  <pre><code>success: function (response, status, xhr) {
        $('.csrftoken').attr('value', response['X-CSRFToken']);
         setCookie(&quot;csrftoken&quot;, response['X-CSRFToken']);
  }
  </code></pre>
  <p>The code above works fine and we get the value, at the start, it was like this but was not working so I changed it like:</p>
  <pre><code>xhr.getResponseHeader(&quot;X-CSRFToken&quot;) -&gt; response['X-CSRFToken']
  </code></pre>
  <p>Now whenever the <strong>frontend</strong> makes a <strong>POST</strong> call to the back end with <code>header:{ 'X-CSRFToken': token}</code> running on <code>localhost:8080</code> it gets <code>Forbidden (CSRF cookie not set.) 403</code></p>
  <h3>settings.py</h3>
  <pre><code>INSTALLED_APPS = [
      'corsheaders,
  ]
  MIDDLEWARE = [
      'corsheaders.middleware.CorsMiddleware',
  ]
  CSRF_COOKIE_HTTPONLY = True
  SESSION_COOKIE_HTTPONLY = True
  CORS_ALLOWED_ORIGINS = [
      &quot;http://localhost:3000&quot;,
      &quot;http://127.0.0.1:3000&quot;
  ]
  </code></pre>
  <h3>The <strong>POST request</strong>:</h3>
  <pre><code>$.ajax({
        type: &quot;POST&quot;,
        headers:{
          'Content-Type': 'application/json',
          'Accept': 'application/json',
          'X-Requested-With': 'XMLHttpRequest',
          'X-CSRFToken': csrftoken,
        },
        url: &quot;/api/userdetails/&quot;,
        data: JSON.stringify(somedata),
        ...
        ...
  })
  </code></pre>
  <h3>What I have tried so far:</h3>
  <p>I have tried to get the <strong>csrftoken</strong> via-</p>
  <pre><code># from the hidden element
  const csrftoken = document.querySelector('.csrftoken').value;
  # from the cookie
  const csrftoken = getCCookie('csrftoken');
  # from the name
  const csrftoken = jQuery(&quot;[name=csrfmiddlewaretoken]&quot;).val();
  </code></pre>
  <p><em><strong>All of these successfully retrieve the value,and i can see the value in request header header but still django says there is no csrftoken</strong></em>
  As the doc says while using the below code in setting one must get the value from the hidden element, again I tried it as well with it without it:</p>
  <pre><code>CSRF_COOKIE_HTTPONLY = True
  SESSION_COOKIE_HTTPONLY = True
  </code></pre>
  <p><a href="https://docs.djangoproject.com/en/2.2/ref/csrf/#setting-the-token-on-the-ajax-request" rel="nofollow noreferrer">Doc</a> says to try this as well:</p>
  <pre><code>function csrfSafeMethod(method) {
    // these HTTP methods do not require CSRF protection
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
  }
  $.ajaxSetup({
          beforeSend: function(xhr, settings) {
              if (!csrfSafeMethod(settings.type) &amp;&amp; !this.crossDomain) {
                  xhr.setRequestHeader(&quot;X-CSRFToken&quot;, csrftoken);
              }
          }
  </code></pre>
  <p>But no successful attempts here, what is wrong with the code? and how should I get past through it.</p>