"Invalid CSRF token or invalid" and post parameter via AJAX in Django

I am trying to post a parameter like

jQuery.ajax( { 'type': 'POST', 'url': url, 'contentType': 'application/json', 'data': "{content:'xxx'}", 'dataType': 'json', 'success': rateReviewResult } ); 

However, Django returns Forbidden 403. CSRF verification failed. Request aborted. Forbidden 403. CSRF verification failed. Request aborted. I am using 'django.middleware.csrf.CsrfViewMiddleware' and cannot find how I can prevent this problem without compromising security.

+55
jquery django django-csrf
Jun 28 2018-11-11T00:
source share
10 answers

You can make an AJAX request in two different ways:

  1. So that your view does not check the csrf token. This can be done using decorator @csrf_exempt , like so:

     from django.views.decorators.csrf import csrf_exempt @csrf_exempt def your_view_name(request): ... 
  2. To embed the csrf token in every AJAX request, for jQuery it could be:

     $(function () { $.ajaxSetup({ headers: { "X-CSRFToken": getCookie("csrftoken") } }); }); 

    Where the getCookie function gets the getCookie token from cookies. I am using the following implementation:

     function getCookie(c_name) { if (document.cookie.length > 0) { c_start = document.cookie.indexOf(c_name + "="); if (c_start != -1) { c_start = c_start + c_name.length + 1; c_end = document.cookie.indexOf(";", c_start); if (c_end == -1) c_end = document.cookie.length; return unescape(document.cookie.substring(c_start,c_end)); } } return ""; } 

    In addition, jQuery has a plugin for accessing cookies, something like this:

     // set cookie $.cookie('cookiename', 'cookievalue'); // read cookie var myCookie = $.cookie('cookiename'); // delete cookie $.cookie('cookiename', null); 
+85
Jun 30 2018-11-11T00:
source share

The easiest way I've found is to include the value {{csrf_token}} in the data:

 jQuery.ajax( { 'type': 'POST', 'url': url, 'contentType': 'application/json', 'data': { 'content': 'xxx', 'csrfmiddlewaretoken': '{{ csrf_token }}', }, 'dataType': 'json', 'success': rateReviewResult } ); 
+38
Jul 29 '11 at 4:10
source share

It took me a while to figure out what to do with the code that Daniel sent. But in fact, all you have to do is insert it at the beginning of the javascript file.

For me, the best solution so far is:

  • Create csrf.js file

  • Paste code in csrf.js file

  • Link to the code in the template you need

     <script type="text/javascript" src="{{ STATIC_PREFIX }}js/csrf.js"></script> 

Please note that STATIC_PREFIX/js/csrf.js points to my file. I actually load the STATIC_PREFIX variable into {% get_static_prefix as STATIC_PREFIX %} .




Extended tip: if you use templates and have something like base.html that you are expanding from, then you can just reference the script and you no longer need to worry about your files otherwise. As I understand it, this should not pose a security problem either.

+22
Apr 30 2018-12-12T00:
source share

Simple and short

 $.ajaxSetup({ headers: { "X-CSRFToken": '{{csrf_token}}' } }); 

OR

 function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", '{{csrf_token}}'); } } }); 

documents

+9
Nov 19 '17 at 9:55 on
source share

Thanks to everyone for all the answers. I am using Django 1.5.1. I'm a little late to the party, but here it goes.

I found a link to the Django project to be very useful, but I really did not want to include additional JavaScript code every time I wanted to make an Ajax call.

I like jerrykan's answer as it is very concise and only adds one line to a regular regular Ajax call. In response to the comments below of his comments regarding situations where Django template tags are not available, how about loading csrfmiddlewaretoken from the DOM?

 var token = $('input[name="csrfmiddlewaretoken"]').prop('value'); jQuery.ajax({ type: 'POST', url: url, data: { 'csrfmiddlewaretoken': token }, dataType: 'json', success: function(data) { console.log('Yippee! ' + data); } }); 

EDIT March 2016

My approach to this problem has changed over the past few years. I add the code below (from Django docs ) to the main.js file and upload it to each page. After that, you will not need to worry about the CSRF token with ajax.

 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; } var csrftoken = getCookie('csrftoken'); 
+4
Jun 13 '13 at 4:02
source share

Yesterday I had the same problem and thought it would help people if there is an easy way to handle this, so I wrote the jQuery plugin for it: jquery.djangocsrf . Instead of adding a CSRF token in each request, he himself intercepts the AjaxSend jQuery event and adds the client cookie to the header.

Here's how to use it:

1- enable it:

 <script src="path/to/jquery.js"></script> <script src="path/to/jquery.cookie.js"></script> <script src="path/to/jquery.djangocsrf.js"></script> 

2- include it in your code:

 $.djangocsrf( "enable" ); 

Django always adds a token to the cookie if your template uses {% csrf_token %} . So that he always adds it, even if you do not use a special tag in your template, use the @ensure_csrf_cookie decorator:

 from django.views.decorators.csrf import ensure_csrf_cookie @ensure_csrf_cookie def my_view(request): return render(request, 'mytemplate.html') 

Note: Im using Django 1.6.2.

+4
Mar 21 '14 at 11:32
source share

Due to the lack of a direct response, you just need to add the X-CSRFToken to the ajax request, which is in the csrftoken cookie. JQuery does not make cookies (for some reason) without a plugin , therefore:

 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> 

and minimal code change:

 $.ajax({ headers: { "X-CSRFToken": $.cookie("csrftoken") }, ... }); 
+4
Feb 16 '17 at 21:55
source share

Include the x-csrftoken in the request:

 var token = $('input[name="csrfmiddlewaretoken"]').prop('value'); jQuery.ajax({ type: 'POST', url: url, beforeSend : function(jqXHR, settings) { jqXHR.setRequestHeader("x-csrftoken", get_the_csrf_token_from_cookie()); }, data: data, dataType: 'json', }); 
+3
Apr 10 '16 at 19:53
source share

The fastest solution without any plugins if you don't embed js in the template:

Put <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script> <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script> <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script> <script type="text/javascript"> window.CSRF_TOKEN = "{{ csrf_token }}"; </script> before the link to the script.js file in the template, then add csrfmiddlewaretoken to the data dictionary:

 $.ajax({ type: 'POST', url: somepathname + "do_it/", data: {csrfmiddlewaretoken: window.CSRF_TOKEN}, success: function() { console.log("Success!"); } }) 

If you embed your js in a template, it's simple: data: {csrfmiddlewaretoken: '{{ csrf_token }}'}

+2
Aug 09 '18 at 12:28
source share

If after reading the other answers someone is still struggling, try the following:

  $.ajax({ type: "POST", beforeSend: function (request) { request.setRequestHeader("X-CSRF-TOKEN", "${_csrf.token}"); }, url: servlet_path, data : data, success : function(result) { console.log("Success!"); } }); 
0
Sep 07 '16 at 11:17
source share



All Articles