CSRF cookie not set django...verification failed
Solution 1
I had the same problem, and resolved it by adding the ensure_csrf_cookie decorator to your view:
from django.views.decorators.csrf import ensure_csrf_cookie
@ensure_csrf_cookie
def yourView(request):
#...
It will set csrftoken in browser cookie and you can make ajax like this
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;
}
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
crossDomain: false, // obviates need for sameOrigin test
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
$.ajax({
url: url,
type: type,
async: async,
data: data,
error: function (e) {},
success: function (data) {
returnFunction(data);
}
});
Solution 2
You use both means to pass CSRF token to template processor
c = {}
c.update(csrf(request))
and RequestContext, while one is enough, see docs. But you use it wrong place, for serving 'POST' request. Those requests are normally sent by your browser when it fills up a form and want to get results.
Your browser renders home.html sending GET request to a server, which is served by
t = get_template('home.html')
html = t.render(ResponseContext({'name':name}))
return HttpResponse(html)
part of your code. And there you do not use any mean to pass csrf token. So when your template processor get_template().render()
is invoked, is has no token in its context, so simply ignores {% csrf_token %} code in template. So you have to either use RequestContext
in t.render(...) part of view, or pass you c
dict there.
You can check it inspecting generated form in a browser window.
UPDATE
In seetings.py
add a comma after 'django.core.context_processors.csrf'
, the way it is now, it just contcatenates strings.
Should be:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.csrf',
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
Solution 3
It seems that You have forgot to pass request to render
Django comes with a special Context class, django.template.RequestContext, that acts slightly differently than the normal django.template.Context. The first difference is that it takes an HttpRequest as its first argument. For example:
In addition to these, RequestContext always uses django.core.context_processors.csrf. This is a security related context processor required by the admin and other contrib apps, and, in case of accidental misconfiguration, it is deliberately hardcoded in and cannot be turned off by the TEMPLATE_CONTEXT_PROCESSORS setting.
So What You need is following
t = get_template('home.html')
c = RequestContext(request, {'name':name})
return HttpResponse(t.render(c))
If You wold like You can check django dock here https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.RequestContext
Solution 4
Start from fixing your HTML (You forgot =):
<form method="POST" action="/search/save">
{% csrf_token %}
<textarea name="content" rows="20" cols="60">{{content}}</textarea><br>
<input type="submit" value="Save Page"/>
</form>
Also:
def home_Page(request):
#if request.method == 'GET':
name='Awais you have visited my website :P'
if request.method == 'POST':
#name = request.POST.get('content')
return render_to_response("search.html", {}, context_instance=RequestContext(request))
return render_to_response("home.html", {'name':name}, context_instance=RequestContext(request))
![Saad Abdullah](https://i.stack.imgur.com/77lCZ.jpg?s=256&g=1)
Saad Abdullah
Toptal: https://www.toptal.com/resume/saad-abdullah
Updated on June 13, 2022Comments
-
Saad Abdullah about 2 years
AoA I am new to Django, I am trying to get data from POST, but getting error CSRF cookie not set, I tried alot to find the solution on google and stackoverflow via google too, but failed
here is the code
views.py
from django.http import HttpResponse from django.template.loader import get_template from django.template import Context from django.template import RequestContext from django.core.context_processors import csrf from django.shortcuts import render_to_response def search_Post(request): if request.method == 'POST': c = {} c.update(csrf(request)) # ... view code here return render_to_response("search.html", c) def search_Page(request): name='Awais you have visited my website :P' t = get_template('search.html') html = t.render(Context({'name':name})) return HttpResponse(html)
HTML File
<p> {{ name }} <form method="POST" action="/save/"> {% csrf_token %} <textarea name="content" rows="20" cols="60">{{content}}</textarea><br> <input type="submit" value="Save Page"/> </form> <div> Cant figure out any solution! :( </div> </p>
url.py
url(r'^home/$', 'contacts.views.home_Page'), url(r'^save/$', 'contacts.views.search_Post'), url(r'^edit/$', 'contacts.views.edit_Page'), url(r'^search/$', 'contacts.views.search_Page'),
settings.py
TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.csrf', 'django.contrib.auth.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', 'django.core.context_processors.media', 'django.core.context_processors.static', 'django.core.context_processors.request', 'django.contrib.messages.context_processors.messages' ) MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', # Uncomment the next line for simple clickjacking protection: # 'django.middleware.clickjacking.XFrameOptionsMiddleware', )
-
Saad Abdullah over 10 yearscould you plz interpret ?
-
Saad Abdullah over 10 yearsi have updated my question by correcting the 'action=' and replacing your code with mine one, it runs perfectly with GET but when i click the form button it gives me error...cookie not set...CSRF verification failed
-
alko over 10 yearsdo you see csrf token in generated html?
-
Saad Abdullah over 10 yearswhat is this ResponseContext?
-
Dmitry Demidenko over 10 yearsCheck the rendered page. Do you have csrf field(hidden input) rendered?
-
Saad Abdullah over 10 yearsno, still get the error FORBIDDEN 403 'CSRF verification failed. Request aborted.' Reason given for failure: CSRF cookie not set.
-
Saad Abdullah over 10 yearsthere is no csrf field in html page
-
oleg over 10 yearshave You reload page after changes made?
-
Saad Abdullah over 10 yearsyup...i have restart the server and reload the page
-
Saad Abdullah over 10 yearsUpdated by question with urls.py and used one request( you taught me alot) and render the page..still csrf field is missing in search.html and get the verification failed error on clicking the POST button...I have made another method for this...check above... and why sould I add colon? 'django.core.context_processors.csrf':, it gives me alist of error when I runserver
-
Saad Abdullah over 10 yearsproblem is solved :) very thanks for your help... i was using this for GET t = get_template('home.html') c = RequestContext(request, {'name':name}) and for your mentioned code in POST...which gave me errors, Replacing the get_template with c = {'name': name} c.update(csrf(request)) solved the problem :) Once again thanks :)
-
alko over 10 yearsIn that case I suggest you mark question answered, either choosing from existing answers or if you not feel it appropriate, adding your own.
-
Kevin Zhao about 8 yearswow! This worked for me, so this keeps the csrf protection on your site, is that correct?
-
Alexandre V. over 6 yearsThis has nothing to do with the question. In addition to that, you have used the term DNS incorrectly. It does not make any sense to use the IP address instead of the hostname.