send csrf_token in JSON request (no ajax)
Asked Answered
G

2

6

I'm trying to send a JSON request to my Django application with a csrf token, but I can't figure out how. I've gotten the token into a variable that I can reference, but I don't know how to send it through the JSON request with fetch. I've added 'csrfmiddlewaretoken': csrftoken into the JSON.stringify part of body, but I'm still getting an error saying 403 Forbidden. Can someone please help me with this? Thank you! (sorry for the weird indentation on the code)

Javascript file:

fetch('/update', {
          method: 'PUT',
          body: JSON.stringify({
            'csrfmiddlewaretoken': csrftoken,
            'liked': true,
            'post_id': parseInt(button.dataset.post_id)
          })
        })

views.py:

data = json.loads(request.body)
        try:
            content = data.get('content')
        except:
            JsonResponse({'error': 'content required'}, status=400)
        try:
            id = data.get('id')
            post = Post.objects.get(id=id)
        except:
            JsonResponse({'error': 'post not found'}, status=400)
        if request.user == post.user:
            post.content = content
            post.save()
            return JsonResponse({'message': f'received: {content}'})
        return JsonResponse({'error': "can't edit this user's posts"}, status=403)
Glue answered 22/7, 2020 at 14:33 Comment(3)
there is no code in here, it's hard to have an idea of what you're doingNaji
Hi Patrick, welcome to Stackoverflow! To make it easier for other users to help you with your issue it's recommended that you share a few snippets of the code you're using, so that they can try to replicate the issue as well :)Isabea
Sorry about that, I just added some codeGlue
M
4

First of all to get the csrf you can use the following code

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;

}

Now that we got the CSRF token, add this line of code into you headers of fetch

'X-CSRFToken':csrftoken,

Refrence

Melancholia answered 22/7, 2020 at 14:50 Comment(1)
I dint provide the Code directly cuz stackoverfolw was showing errors, sorry for thatMelancholia
K
1

First, from Andrea and Gabcvit, some pieces of code will be greatly appreciated.

Editing Farhan's answer: you need to manually retrieve the csrf token as there isn't a default in javascript for you to do so. You can do this by:

import jQuery from 'jquery';  // important dependency

function getCookie(name) {
  let cookieValue = null;
  if (document.cookie && document.cookie !== '') {
    let cookies = document.cookie.split(';');
    for (let i = 0; i < cookies.length; i++) {
      let cookie = jQuery.trim(cookies[i]);
      if (cookie.substring(0, name.length + 1) === (name + '=')) {
          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
          break;
      }
    }
  }
  return cookieValue;
}

var csrftoken = getCookie('csrftoken');

In case that React didn't receive Django's csrf token (which happened in my case), you need to add the following code above your view:

@method_decorator(ensure_csrf_cookie, name='dispatch')
class UserLoginView(View):
    # ...

In case you need more help, this MDN article will help you.

Knp answered 22/7, 2020 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.