POST method always return 403 Forbidden POST method always return 403 Forbidden django django

POST method always return 403 Forbidden


I maybe wrong however I found the above solutions rather complex.

what worked for me was simply including my csrf token into my post request.

$.ajax({    type: "POST",    url: "/reports/",    data: { csrfmiddlewaretoken: "{{ csrf_token }}",   // < here             state:"inactive"           },    success: function() {        alert("pocohuntus")        console.log("prototype")    }})


This answer is for people that may encounter this same problem in the future.

The CSRF {{csrf_token}} template tag that is required for forms in Django prevent against Cross Site Request Forgeries. CSRF makes it possible for a malicious site that has been visited by a client's browser to make requests to your own server. Hence the csrf_token provided by django makes it simple for your django server and site to be protected against this type of malicious attack. If your form is not protected by csrf_token, django returns a 403 forbidden page. This is a form of protection for your website especially when the token wasn't left out intentionally.

But there are scenarios where a django site would not want to protect its forms using the csrf_token. For instance, I developed a USSD application and a view function is required to receive a POST request from the USSD API. We should note that the POST request was not from a form on the client hence the risk of CSRF impossible, since a malicious site cannot submit requests. The POST request is received when a user dials a USSD code and not when a form is submitted.

In other words, there are situations where a function will need to get a POST request and there would not be the need of {{csrf_token}}.

Django provides us with a decorator @csrf_exempt. This decorator marks a view as being exempt from the protection ensured by the middleware.

from django.views.decorators.csrf import csrf_exemptfrom django.http import HttpResponse@csrf_exemptdef my_view(request):    return HttpResponse('Hello world')

Django also provides another decorator that performs the same function with {{csrf_token}}, but it doesn't reject incoming request. This decorator is @requires_csrf_token. For instance:

@requires_csrf_tokendef my_view(request):    c = {}    # ...    return render(request, "a_template.html", c)

The last decorator that will be mentioned in this post does exactly the same thing as {{csrf_token}} and it is called @csrf_protect. However, the use of this decorator by itself is not best practice because you might forget to add it to your views. For instance:

@csrf_protectdef my_view(request):    c = {}    # ...    return render(request, "a_template.html", c)

Below are some links that will guide and explain better.

https://docs.djangoproject.com/en/1.7/ref/contrib/csrf/#module-django.views.decorators.csrf

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

http://www.squarefree.com/securitytips/web-developers.html#CSRF


The easiest way to avoid such problems is to use the render shortcut.

from django.shortcuts import render# .. your other importsdef search_form(request):    return render(request, 'library/search_form.html')def search(request):    q = request.GET.get('q')    results = BookModel.objects.all()    if q:        results = results.filter(title__icontains=q)    return render(request, 'library/search.html', {'result': results})