Search code examples
ajaxdjangodjango-csrf

Django doesn't check for a csrf token with Ajax post


According to the Django docs, Django should have csrf token validation enabled by default, using a middleware. When I look in my settings file I indeed see the middleware being included.

However, when I do a post request without a csrf token using Ajax, Django will just allow it. Should it not return an error saying the csrf token is invalid? I am seeing a lot of questions from people who can't get their csrf token validated, but I can't get it INvalidated.

This is my Ajax post function (I collect the data from my inputs with js, and pass it to this function):

function ajaxPost(url, data, success) {
fetch(url, {
    method: 'POST', // or 'PUT'
    body: JSON.stringify(data),
    headers: new Headers({
        'Content-Type': 'application/json'
    })
}).then(res => res.json())
    .then(response => {
        if (response.status !== success) {
            //errors
        }
        updateView(response);
    })
    .catch(error => console.error('Error:', error))
}

And this is my view function:

@api_view(['POST'])
# API endpoint for posting bulk properties
def bulk(request):
    new_properties = []
    if request.method == 'POST':
        for obj in request.data:
            discipline = Discipline.objects.get(pk=obj['discipline.id'])
            root_function = Function.objects.get(pk=obj['root_function'])
            new_property = Property(name=obj['name'], value=obj['value'], unit=obj['unit'],
                                    discipline_id=discipline)
        new_property.save()
        new_property.function.add(root_function)
        new_properties.append(new_property)

    new_properties = json.loads(serializers.serialize('json', new_properties))

    return JsonResponse({'status': 201, 'new_properties': new_properties})

Solution

  • Assuming api_view is the one from django-rest-framework, it disables CSRF protection for that view.

    This is because API endpoints are frequently used for external requests that won't have a CSRF token; there's no point checking for it in these cases.