Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 358 Vote(s) - 3.42 Average
  • 1
  • 2
  • 3
  • 4
  • 5
403 Forbidden error when making an ajax Post request in Django framework

#1
I am trying to integrate jquery into a web application I am making with Django framework. I am however having a hard time trying to make a simple `ajax` call to work. My template file that contains the form html and javascript to handle the ajax call looks like:

<script type="text/javascript">
$(document).ready(function() {
$( "#target" ).submit(function() {
console.log('Form was submitted');
$.ajax({
type: "POST",
url: "/hello/", // or just url: "/my-url/path/"
data: {
query: $( "#query" ).val()
},
success: function(data) {
console.log(data);
}
});
return false;
});
})
</script>
<form id="target" action="." method="post">{% csrf_token %}
<input id= "query" type="text" value="Hello there">
<input type="submit" value="Search Recent Tweets">
</form>

My `views.py` that is supposed to handle the ajax call looks like:

from django.core.context_processors import csrf
from django.shortcuts import render_to_response
from django.template.loader import get_template
from django.template import Context,RequestContext
from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponse

# access resource
def hello(request):
c = {}
c.update(csrf(request))
if request.is_ajax():
t = get_template('template.html')
#html = t.render(Context({'result': 'hello world'}))
con = RequestContext(request, {'result': 'hello world'})
return render_to_response('template.html', c, con)
else:
return HttpResponse('Not working!')


I have tried to follow the official documentation on [Cross-Site Request Forgery Protection](

[To see links please register here]

) and also looked at several stackoverflow questions addressing a similar problem. I have included the `{% csrf_token %}` in my `html` template file but it still doesn't seem to be working. I get an error in the console suggesting that the ajax call failed:

POST

[To see links please register here]

403 (FORBIDDEN)

How do I pass the `result` variable along with my http response and get the ajax call to work smoothly? Any help is deeply appreciated.

**Edit-1**

I wasn't supposedly passing the `csrf` token along with my post request. SO as per the documentation I added the following code to my template javascript:


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');
console.log(csrftoken);

//Ajax call
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", csrftoken);
}
}
});

When I refresh the template html page in the browser, I get `null` in the console, suggesting that the cookie is not set or not defined. What am I missing?
Reply

#2
For the lazy guys:

First download cookie:

[To see links please register here]


Add it to your html:

<script src="{% static 'designer/js/jquery.cookie.js' %}"></script>

Now you can create a working POST request:

var csrftoken = $.cookie('csrftoken');

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", csrftoken);
}
}
});

$.ajax(save_url, {
type : 'POST',
contentType : 'application/json',
data : JSON.stringify(canvas),
success: function () {
alert("Saved!");
}

})
Reply

#3
Make sure you aren't caching the page/view that your form is showing up on. It could be caching your CSRF_TOKEN. Happened to me!
Reply

#4
To set the cookie, use the [`ensure_csrf_cookie`][1] decorator in your view:


from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def hello(request):
code_here()


[1]:

[To see links please register here]

Reply

#5
I find all previous answers on-spot but let's put things in context.

The 403 forbidden response comes from the CSRF middleware (see [Cross Site Request Forgery protection][1]):

> By default, a ‘403 Forbidden’ response is sent to the user if an incoming request fails the checks performed by CsrfViewMiddleware.

Many options are available. I would recommend to follow the [answer of @fivef][2] in order to make jQuery add the `X-CSRFToken` header before every AJAX request with `$.ajaxSetup`.

This answer requires the cookie jQuery plugin. If this is not desirable, another possibility is to add:

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');

BUT: if the setting [`CSRF_COOKIE_HTTPONLY`][3] is set to True, which often happens as the [Security middleware][4] recommends so, then the cookie is not there, even if `@ensure_csrf_cookie()` is used. In this case `{% csrf_token %}` must be provided in every form, which produces an output such as `<input name="csrfmiddlewaretoken" value="cr6O9...FUXf6" type="hidden">`. So the `csrfToken` variable would simply be obtained with:

var csrftoken = $('input[name="csrfmiddlewaretoken"]').val();

Again `$.ajaxSetup` would be required of course.

Other options which are available but **not recommended** are to disable the middleware or the csrf protection for the specific form with `@csrf_exempt()`.


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

[4]:

[To see links please register here]

Reply

#6
Because you did not post the **csrfmiddlewaretoken**, so Django forbid you.
[this document][1] can help you.


[1]:

[To see links please register here]

Reply

#7
You must change your folder chmod 755 and file(.php ,.html) chmod 644.
Reply

#8
Try including this decorator on your dispatch code


from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
@method_decorator(csrf_exempt, name='dispatch')
def dispatch(self, request, *args, **kwargs):
return super(LessonUploadWorkView,self).dispatch(request,*args,**kwargs)

Reply

#9
With SSL/https and with CSRF_COOKIE_HTTPONLY = False, I still don't have csrftoken in the cookie, either using the *getCookie(name)* function proposed in [django Doc][1] or the *jquery.cookie.js* proposed by [fivef][2].

[Wtower][3] summary is perfect and I thought it would work after removing CSRF_COOKIE_HTTPONLY from settings.py but it does'nt in https!

**Why csrftoken is not visible in document.cookie???**

Instead of getting

> "django_language=fr; csrftoken=rDrGI5cp98MnooPIsygWIF76vuYTkDIt"

I get only

> "django_language=fr"

WHY? Like

[To see links please register here]

I thought it was due to the proxy header params of Nginx but apparently not... Any idea?

Unlike [django doc Notes][1], it seems impossible to work with csrf_token in cookies with https. The only way to pass csrftoken is through the DOM by using {% csrf_token %} in html and get it in jQuery by using

var csrftoken = $('input[name="csrfmiddlewaretoken"]').val();

It is then possible to pass it to ajax either by header ([xhr.setRequestHeader][4]), either by [params][5].


[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

[4]:

[To see links please register here]

[5]:

[To see links please register here]

Reply

#10
The fastest solution if you are not embedding js into your template is:

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

$.ajax({
type: 'POST',
url: somepathname + "do_it/",
data: {csrfmiddlewaretoken: window.CSRF_TOKEN},
success: function() {
console.log("Success!");
}
})
If you do embed your js into the template, it's as simple as: `data: {csrfmiddlewaretoken: '{{ csrf_token }}'}`
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through