2

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.

6
  • can you show us the actual View you are using??? the function token is not the actual view right??? Commented Jul 23, 2018 at 7:09
  • I added the view I have been testing with, but if I understand correctly CSRF is checked at every view. Commented Jul 23, 2018 at 7:39
  • 1
    Official docs say: if CSRF_USE_SESSIONS is True (default False) django store the CSRF token in the user’s session instead of in a cookie. It requires the use of django.contrib.sessions. Have you changed the parameter??? docs.djangoproject.com/en/2.0/ref/settings/#csrf-use-sessions Commented Jul 23, 2018 at 9:04
  • I had! Now I am able to print the csrf key to the console, but django still says the CSRF cookie is not set. Commented Jul 23, 2018 at 10:02
  • I had a similar issue and passed 'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val(), in my jquery data to solve it. Commented Jul 23, 2018 at 10:36

1 Answer 1

1

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
      },
  });

};
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you so much for the response.
Sadly the developer who started the project choose to use fetch instead of ajax, so Im having a hard time using your code.
When is the csrf key provided? This confuses me. My site first page is only a log in page, so there is not view that could do ensure_csrf. And I cannot find any cookies at all in the page.
If your react is a separate app then you can explicitly set the CSRF using @ensure_csrf_cookie attribute.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.