简体   繁体   中英

Forbidden 403 during CSRF check with an AJAX POST request in Django

I can't fix the problem with CSRF check. Could you please tell me what I need to do? This is my function from views.py:

@login_required
def like_day(request):
if request.method == 'POST':
    if 'day_id' in request.POST:
        day_id = request.POST['day_id']
        if day_id:
            day = Day.objects.get(id=int(day_id))
            likes = day.likes + 1
            day.likes = likes
            day.save()
            return HttpResponse(likes)

This is AJAX request:

$(document).ready( function(){
    $('#likes2').click(function(){
        var catid;
        protect
        catid = $(this).attr("data-catid");
        $.post('/friends_plans/like_day/', {day_id: catid}, function(data){
            $('#like_count').html(data);
            $('#likes2').hide();
        });
    });
});

I've tried to use @ensure_csrf_cookie decorator forthe function, but it didn't help. I've tried to add this to my code:

$.ajaxSetup({
    data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});

It didn't help either. I've done as it is described in the documentation: https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/ but then there is a mistake $.cookie is not a function. To cope with this problem I downloaded csrf cookie plugin to my static directory or add this to my template <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> , but still the same mistake.

You can add {% csrf_token %} template tag in your form or posting function the make posting , if you want to avoid the error you can use decorater @csrf_exempt

 from django.views.decorators.csrf import csrf_exempt
    @csrf_exempt
    def hello(request):
       if request.is_ajax():
          print "hello is working fine"

more details : https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/

To account for CSRF using ajax, try following the Django docs suggestion of aquiring the token via JS: https://docs.djangoproject.com/en/1.9/ref/csrf/#ajax

Create a JS file called csrf.js using the following (assuming 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;
}
var csrftoken = getCookie('csrftoken');

Include that JS file on the template containing your ajax JS.

You should then be able to do what you need safely.

I was also facing the same issue, but it got resolved.

Information: I had a basic contact form which makes POST request to Django View '/contact-form'. But it was giving '403 Forbidden' error. The HTML is as follows:

<form method="post">
    {% csrf_token %}
    <input>...</input>
    <button id="contact-form" type="submit"> <span>Envoyer</span</button>
</form>

Reason: It says that the Django Url is protected by any forgery and you should include a CSRF token in you Ajax call.

Solution: 1) Get CSRF token before making Ajax request like this:

var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();

2) And then include csrftoken in you Ajax request header like this:

        jQuery.ajax({
            type: "POST",
            url: "/contact-form/",
             headers: {
                'X-CSRFToken': csrftoken
           },
            data: data,
            success: function() {
                alert('success');
            }
        });

When you use csrfmiddlewaretoken in your templates you use {% csrf_token %} ie include in somewhere in your html body. {% csrf_token %} is evaluated to

<input type="hidden" name="csrfmiddlewaretoken" value="somevalue">

You can then use jquery to lookup this particular hidden field and retrieve its value and pass it in your ajax call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM