Kluckmuck
Kluckmuck

Reputation: 117

Setting Django CSRF Cookie

I'm using React as front and Django as back. Httprequest fails, prompting that the CSRF Cookie is not set. I have followed the django docs,I have this code:

var jQuery = require("jquery");
// using jQuery
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]);
            // 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;
}

let header = new Headers({
  "X-CSRFToken": getCookie("csrftoken"),
  "Content-Type": "application/json; charset=utf-8",
  "Access-Control-Request-Headers": "*",
  "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS, PUT, DELETE, PATCH"
});

Using console.log(getCookie("csrftoken")); prints null, which leads me to believe that Django is not setting the cookie.

My middleware looks like this:

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Early in development I used this view for testing:

@ensure_csrf_cookie
def token(request):
    if request.method == 'GET':
        return HttpResponse(status=204)
    else:
        return HttpResponseNotAllowed(['GET'])

This works well, but it does not feel very clean to call this everytime the user uses the website.

The view that is failing:

def loginView(request):
    if request.method == 'POST':
        username = json.loads(request.body.decode())['username']
        password = json.loads(request.body.decode())['password']
        user = authenticate(username=username, password=password)
        if user is not None:
            login(request, user)
            return HttpResponse(status=200) #OK
        else:
            return HttpResponse(status=401) #DENIED
    else:
        return HttpResponseNotAllowed(['POST'])

I am using a few more views, and they also fail if I do not provide a CSRF key.

Upvotes: 2

Views: 1608

Answers (1)

Ashish
Ashish

Reputation: 266

As mentioned in the comment. I passed on the value of csrf token via my jquery as below. May be you can try the same.

function getDetail(e){

  $.ajax({
      type: "POST",
      url: "/result/",
      data: {
            'search': $(this).text(),
            'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
      },
      dataType:'html',
      success: function(data) {
          # Do other stuff
      },
  });

};

Upvotes: 1

Related Questions