python - Django CSRF check failing with an Ajax POST request -
i use complying django's csrf protection mechanism via ajax post. i've followed directions here:
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/
i've copied ajax sample code have on page exactly:
http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
i put alert printing contents of getcookie('csrftoken')
before xhr.setrequestheader
call , indeed populated data. i'm not sure how verify token correct, i'm encouraged it's finding , sending something.
but django still rejecting ajax post.
here's javascript:
$.post("/memorize/", data, function (result) { if (result != "failure") { get_random_card(); } else { alert("failed save card data."); } });
here's error i'm seeing django:
[23/feb/2011 22:08:29] "post /memorize/ http/1.1" 403 2332
i'm sure i'm missing something, , maybe it's simple, don't know is. i've searched around , saw information turning off csrf check view via csrf_exempt
decorator, find unappealing. i've tried out , works, i'd rather post work way django designed expect it, if possible.
just in case it's helpful, here's gist of view doing:
def myview(request): profile = request.user.profile if request.method == 'post': """ process post... """ return httpresponseredirect('/memorize/') else: # request.method == 'get' ajax = request.get.has_key('ajax') """ irrelevent code... """ if ajax: response = httpresponse() profile.get_stack_json(response) return response else: """ data send along content of page. """ return render_to_response('memorize/memorize.html', """ data """ context_instance=requestcontext(request))
thanks replies!
real solution
ok, managed trace problem down. lies in javascript (as suggested below) code.
what need this:
$.ajaxsetup({ beforesend: function(xhr, settings) { function getcookie(name) { var cookievalue = null; if (document.cookie && document.cookie != '') { var cookies = document.cookie.split(';'); (var = 0; < cookies.length; i++) { var cookie = jquery.trim(cookies[i]); // cookie string begin name want? if (cookie.substring(0, name.length + 1) == (name + '=')) { cookievalue = decodeuricomponent(cookie.substring(name.length + 1)); break; } } } return cookievalue; } if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) { // send token relative urls i.e. locally. xhr.setrequestheader("x-csrftoken", getcookie('csrftoken')); } } });
instead of code posted in official docs: http://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#ajax
the working code, comes django entry: http://www.djangoproject.com/weblog/2011/feb/08/security/
so general solution is: "use ajaxsetup handler instead of ajaxsend handler". don't know why works. works me :)
previous post (without answer)
i'm experiencing same problem actually.
it occurs after updating django 1.2.5 - there no errors ajax post requests in django 1.2.4 (ajax wasn't protected in way, worked fine).
just op, have tried javascript snippet posted in django documentation. i'm using jquery 1.5. i'm using "django.middleware.csrf.csrfviewmiddleware" middleware.
i tried follow the middleware code , know fails on this:
request_csrf_token = request.meta.get('http_x_csrftoken', '')
and then
if request_csrf_token != csrf_token: return self._reject(request, reason_bad_token)
this "if" true, because "request_csrf_token" empty.
basically means header not set. there wrong js line:
xhr.setrequestheader("x-csrftoken", getcookie('csrftoken'));
?
i hope provided details in resolving issue :)
Comments
Post a Comment