source:http://stackoverflow.com/questions/6506897/csrf-token-missing-or-incorrect-while-post-parameter-via-ajax-in-django/6533544#6533544
question:
answer:
Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import django
>>> django.VERSION
(1, 6, 0, 'final', 0)
1 $(document).ajaxSend(function(event, xhr, settings) {
2 function getCookie(name) {
3 var cookieValue = null;
4 if (document.cookie && document.cookie != '') {
5 var cookies = document.cookie.split(';');
6 for (var i = 0; i < cookies.length; i++) {
7 var cookie = jQuery.trim(cookies[i]);
8 // Does this cookie string begin with the name we want?
9 if (cookie.substring(0, name.length + 1) == (name + '=')) {
10 cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
11 break;
12 }
13 }
14 }
15 return cookieValue;
16 }
17 function sameOrigin(url) {
18 // url could be relative or scheme relative or absolute
19 var host = document.location.host; // host + port
20 var protocol = document.location.protocol;
21 var sr_origin = '//' + host;
22 var origin = protocol + sr_origin;
23 // Allow absolute or scheme relative URLs to same origin
24 return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
25 (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
26 // or any other URL that isn't scheme relative or absolute i.e relative.
27 !(/^(\/\/|http:|https:).*/.test(url));
28 }
29 function safeMethod(method) {
30 return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
31 }
32
33 if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
34 xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
35 }
36 });
1 from django.conf.urls import patterns, include, url
2
3 from django.contrib import admin
4 admin.autodiscover()
5
6 from mainpage.views import index_handler, ajax_handler
7
8 urlpatterns = patterns('',
9 # Examples:
10 # url(r'^$', 'ajax_test.views.home', name='home'),
11 # url(r'^blog/', include('blog.urls')),
12
13 url(r'^admin/', include(admin.site.urls)),
14 url(r'^$', index_handler),
15 url(r'^ajax_handler$', ajax_handler),
16 )
question:
I try to post parameter like
jQuery.ajax(
{
'type': 'POST',
'url': url,
'contentType': 'application/json',
'data': "{content:'xxx'}",
'dataType': 'json',
'success': rateReviewResult
}
);
However, Django return
Forbidden 403. CSRF verification failed. Request aborted.
I am using 'django.middleware.csrf.CsrfViewMiddleware'
and couldn't find how I can prevent this problem without compromising security.answer:
It took me a while to understand what to do with the code that Daniel posted. But actually all you have to do is paste it at the beginning of the javascript file.
For me, the best solution so far is:
- Create a csfr.js file
- Paste the code in csfr.js file
- Reference the code in the template you need it
<script type="text/javascript" src="{{ STATIC_PREFIX }}js/csrf.js"></script>
Notice that
STATIC_PREFIX/js/csfr.js
points to my file. I am actually loading the STATIC_PREFIX
variable with {% get_static_prefix as STATIC_PREFIX %}
.
AN EXTRA TIP: if you are using templates and have something like base.html where you extend from, then you can just reference the script from there and you don't have to worry any more in there rest of your programming. As far as I know, this shouldn't represent any security issue
----------------------------------------------------------------------------------------------------------------------------------------
my solution in detail:
Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import django
>>> django.VERSION
(1, 6, 0, 'final', 0)
/app1/static/app1/js/csrf.js:
2 function getCookie(name) {
3 var cookieValue = null;
4 if (document.cookie && document.cookie != '') {
5 var cookies = document.cookie.split(';');
6 for (var i = 0; i < cookies.length; i++) {
7 var cookie = jQuery.trim(cookies[i]);
8 // Does this cookie string begin with the name we want?
9 if (cookie.substring(0, name.length + 1) == (name + '=')) {
10 cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
11 break;
12 }
13 }
14 }
15 return cookieValue;
16 }
17 function sameOrigin(url) {
18 // url could be relative or scheme relative or absolute
19 var host = document.location.host; // host + port
20 var protocol = document.location.protocol;
21 var sr_origin = '//' + host;
22 var origin = protocol + sr_origin;
23 // Allow absolute or scheme relative URLs to same origin
24 return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
25 (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
26 // or any other URL that isn't scheme relative or absolute i.e relative.
27 !(/^(\/\/|http:|https:).*/.test(url));
28 }
29 function safeMethod(method) {
30 return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
31 }
32
33 if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
34 xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
35 }
36 });
/app1/templates/app1/index.html (django template)
1 <html>
2 <head>
3 <title>Ajax Testing Page</title>
4
5 {% load staticfiles %}
6 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <!--this should be positioned earlier than including csrf.js -->
7 <script src="{% static "mainpage/js/csrf.js" %}"></script>
8 <script>
9 $(document).ready(function(){
10 $("#button1").click(function(){
11 $.get("ajax_handler", function(data,status){
12 alert("Data: " + data + "\nStatus: " + status);
13 });
14 });
15 });
16
17 $(document).ready(function(){
18 $("#button2").click(function(){
19 $.post("ajax_handler",
20 {
21 name:"Donald Duck",
22 city:"Duckburg"
23 },
24 function(data,status){
25 alert("Data: " + data + "\nStatus: " + status);
26 });
27 });
28 });
29 </script>
30 </head>
31
32 <body>
33 <button id="button1">Send an HTTP GET request to a page and get the result back</button><br/>
34 <button id="button2">Send an HTTP POST request to a page and get the result back</button>
35 </div>
36 </body>
37
38 </html>
/app1/views.py:
1 from django.shortcuts import render, render_to_response
2 import json
3 from django.http import HttpResponse
4
5 def index_handler(request):
6 return render(request, 'mainpage/index.html', locals())
7
8
9 def ajax_handler(request):
10 if request.is_ajax() and request.method == 'GET':
11 response_dict = {}
12 return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
13
14 elif request.is_ajax() and request.method == 'POST':
15 response_dict = {}
16 return HttpResponse(json.dumps(response_dict), content_type='application/javascript')
17
18 else:
19 assert(False) #should be changed.
/myproject/urls.py:
2
3 from django.contrib import admin
4 admin.autodiscover()
5
6 from mainpage.views import index_handler, ajax_handler
7
8 urlpatterns = patterns('',
9 # Examples:
10 # url(r'^$', 'ajax_test.views.home', name='home'),
11 # url(r'^blog/', include('blog.urls')),
12
13 url(r'^admin/', include(admin.site.urls)),
14 url(r'^$', index_handler),
15 url(r'^ajax_handler$', ajax_handler),
16 )
댓글
댓글 쓰기