Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I be getting a 403 Forbidden error when using @csrf_exempt in AJAX request?

I am trying to write a very basic AJAX request in Django, and I keep getting the 403 forbidden error in both the Chrome Dev and Django consoles. I posted a similar question the other day and have tried all of the proposed solutions including @csrf_exempt (to rule out if this is even a csrf issue), I have tried including csrfmiddlewaretoken: '{{ csrf_token }}' in the AJAX POST request (underneath data), this did not resolve the issue either. Here is my code.

def profile_listview(request, username,
    template_name=userena_settings.USERENA_PROFILE_DETAIL_TEMPLATE,
    extra_context=None, **kwargs):
    user = get_object_or_404(get_user_model(),
                             username__iexact=username)
    fullsalelist = Entry.objects.filter(author__username__iexact=username)

    @csrf_exempt
    def delete_object(request):
        if request.is_ajax():
            print "request is ajax"
            object_name = request.POST.get('entryname')
            targetobject = Entry.objects.get(headline=object_name)
            if request.user.username == targetobject.author:
                targetobject.delete()
                print "hello" 
            return HttpResponseRedirect('/storefront/')

And AJAX code in the template:

<script type="text/javascript">
    var my_app = {
      username: "{{ request.user.username }}"  
    };
</script>

<script>
 $(document).ready(function() {
    $(".delete_button").click(function() {
        var id = $(this).attr('id');
        $.ajax({
            type: "POST",
            url: "/accounts/" + my_app.username + "/listview/",
            data: { entryname:id },
        });
        return false;
    });
});
</script>

URLS

(r'^accounts/(?P<username>[\@\.\w-]+)/listview/$', profile_listview),

Things worth noting:

  1. I have csrf middleware turned on in my settings

  2. inside the jQuery AJAX code, url and data are both sending the correct information

  3. When I click the delete button, I get the 403 forbidden error.

  4. The print "request is ajax" does not print in the console (or anywhere).

I am also confused because I am getting conflicting information. I was told I should add the csrf value via javascript (https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/). This leaves me with 2 questions. 1. How is this any different than adding csrfmiddlewaretoken: '{{ csrf_token }}' in my POST request? and 2. More importantly, doesn't the fact that I still get a 403 error when using @csrf_exempt kind of make this a moot point?

like image 860
stephan Avatar asked Jan 16 '15 18:01

stephan


1 Answers

The @csrf_exempt needs to be before the function that is called by urls.py. In the OP's example, delete_object was never called because the error happened already when calling profile_listview which didn't have the decorator.

On a side note, one can have a similar situation (using @csrf_exempt but getting 403) if the URL doesn't exist. For some reason (security?), it will return a 403 rather than a 404 so it can be hard to debug.

like image 115
RubberDuckRabbit Avatar answered Oct 19 '22 18:10

RubberDuckRabbit