I have read Django - CSRF verification failed and several questions (and answers) related to django and POST method. One of the best-but-not-working-for-me answer is https://stackoverflow.com/a/4707639/755319
All of the approved answers suggest at least 3 things:
I've done exactly as suggested, but the error still appeared. I use django 1.3.1 (from ubuntu 12.04 repository) and python 2.7 (default from ubuntu)
This is my View:
# Create your views here.
from django.template import RequestContext
from django.http import HttpResponse
from django.shortcuts import render_to_response
from models import BookModel
def index(request):
return HttpResponse('Welcome to the library')
def search_form(request):
return render_to_response('library/search_form.html')
def search(request):
if request.method=='POST':
if 'q' in request.POST:
q=request.POST['q']
bookModel = BookModel.objects.filter(title__icontains=q)
result = {'books' : bookModel,}
return render_to_response('library/search.html', result, context_instance=RequestContext(request))
else:
return search_form(request)
else:
return search_form(request)
and this is my template (search_form.html):
{% extends "base.html" %}
{% block content %}
<form action="/library/search/" method="post">
{% csrf_token %}
<input type="text" name="q">
<input type="submit" value="Search">
</form>
{% endblock %}
I've restarted the server, but the 403 forbidden error is still there, telling that CSRF verification failed.
I've 2 questions:
The simple answer is; “You need to be given the correct access”. Without being given the correct access you'd technically be hacking the server, as it is specifically set up to restrict said access.
The 403 Forbidden error appears when your server denies you permission to access a page on your site. This is mainly caused by a faulty security plugin, a corrupt . htaccess file, or incorrect file permissions on your server.
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_exempt
from django.http import HttpResponse
@csrf_exempt
def 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_token
def 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_protect
def 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With