Skip to content
Advertisement

Error :Forbidden (CSRF token missing or incorrect.) while using django rest framework

I use in my study project django rest framework.I get an error 403 Forbidden (CSRF token missing or incorrect, when I try to save using the POST method. Here is my code html

<form id = "product_form" method = "post">
    {% csrf_token %}
    <input type = "hidden" name = "id" id = "id">
    <p>Назвние:<input name = "name" id = "name"></p>
    <p><input type = "reset" value = "Oчистить"></p>
    <input type = "submit" value = "Сохранить">
</form>

Here is my code js:

let productUpdater = new XMLHttpRequest();
productUpdater.addEventListener('readystatechange', () => {

        if (productUpdater.readyState == 4) {
            if ((productUpdater.status == 200) || (productUpdater.status == 201)) {
                listLoad();
                name.form.reset();
                id.value = '';
            } else {
                window.alert(productUpdater.statusText)
            }
        }
    }
);


name.form.addEventListener('submit', (evt) => {
    evt.preventDefault();
    // let vid = id.value, url, method;
    let vid = id.value;
    if (vid) {
        url = 'http://127.0.0.1:8000/books/api_category/' + vid + '/';
        method = 'PUT';
    } else {
        url = 'http://127.0.0.1:8000/books/api_category/';
        method = 'POST';
    }
    let data = JSON.stringify({id: vid,nameCategory: name.value});
    productUpdater.open(method, url, true);
    productUpdater.setRequestHeader('Content-Type', 'application/json');
    productUpdater.send(data);
})

Here is my views.py:

@api_view(['GET', 'POST'])
def api_products(request):
    if request.method == 'GET':
        productsAll = CategoryMaskarad.objects.all()
        serializer = CategorySerializer(productsAll, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = CategorySerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET', 'PUT', 'PATCH', 'DELETE'])
def api_rubric_detail(request, pk):
    product = CategoryMaskarad.objects.get(pk=pk)
    if request.method == 'GET':
        serializer = CategorySerializer(product)
        return Response(serializer.data)
    elif request.method == 'PUT' or request.method == 'PATCH':
        serializer = CategorySerializer(product, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        product.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Here is my urls.py:

 path('api_category/<int:pk>/', api_rubric_detail),
 path('api_products/', api_products),
 path('api/drf-auth/', include('rest_framework.urls'))

I added the last path and logged in. In the api interface it became possible to add to the api using the post method, but with the help of js in my html I cant add data.Help me, please

Advertisement

Answer

when passing data in form to a django rest framework, you do not add the csrf_token tag before forms, rather you pass it as a header when sending api post on your endpoint. Add this line after

try adding this function into your codes to get the values of csrftoken

let 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();
            if(cookie.substring(0, name.length+1)===(name+'=')){
              cookieValue = decodeURIComponent(cookie.substring(name.length+1));
              break;
            }
          }
        }
        return cookieValue;
      }
      
      

and then change the value you use in x-csrf-token and make it

productUpdater.setRequestHeader(‘Content-Type’, ‘application/json’);

productUpdater.setRequestHeader(‘X-CSRF-Token’, getCookie(“csrftoken”));

Advertisement