CSRF Failed after sent correct CSRF token - django-rest-framework

I'm using django restframe work,When I use browser to sent PUT request, it works well.but When I using ajax sent request just like before, it tell me csrf token is missing or incorrected.
My jQuery code looks like this:
$.ajax({
url: "/api/users/1/",
type: "PUT",
datatype: "json",
data: {csrfmiddlewaretoken: csrf_token, "user_gender": 2, "user_details": 23 },
....
In chrome console
csrfmiddlewaretoken:wUlPIaEmZd2FMA2ob9VRSVKWpOf6EQHn
user_gender:0
user_details:111asdfasdfsdf
I'd console.log(csrf_token), and it is as same as which I using in brower.
I followed Bryan here Django CSRF check failing with an Ajax POST request and it works in other page using POST request.

Django documentation says, that you may put csrf-token in X-CSRFToken header in your AJAX request: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax

Related

Access response data in JSONP request

I have a SAP Gateway OData-Service and a local Tomcat Apache Server. My SAPUI5 Client is deployed in the Tomcat and requests a OData-Webservice from the SAP Gateway remote server. In fact there is a cross origin domain error. So I set the header "Access-Control-Allow-Origin" in my OData-Webservice and my SAPUI5 client requests with JSONP, but I will get an error because the SAP Gateway can't handle with JSONP responses.
My code:
The error: "Uncaught SyntaxError: Unexpected token :"
The error depends on the incompatibility of the SAP Gateway to JSONP.
If I look in the network requests I will find this one:
It is the JSON (not JSONP) response from the webservice.
So my question. Is there a possibility to access to this response?
I tried to access via a lot of callbacks like success, error, fail, done, always, complete, and so on. But no chance...
thanks and best regards
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(response) {
//this is where you'll get data/response
console.log(response) ;
},
error: function(e) {
console.log(e.message);
}
});
Update:
Problem is with your context.. there is some value like _1453458442107=:1
Check that and encode it.
If you set the CORS header "Access-Control-Allow-Origin" in the odata responses you should be able to access the service with regular JSON (without the P).
JSONP is a workaround to circumvent the same origin policy when the CORS-Headers are not available.
If your odata service uses authentification it might be necessary to set some more CORS headers to get it working.
On MDN you can read more about CORS and its headers.
On Wikipedia is a chapter about CORS vs JSONP.
So have you tried something like the following?
$.get({
url:"https://.../sap/opu/odata/sap/ZMOBILAD_SRV/UsernameSet?$format=json",
context: document.body,
cache: false
}).done(function(){
console.log(this);
});

Cross-domain AJAX POST withCredentials and IE8+ compatibility

I have a login setup for one of my sites where the user types their information into a login popup on the home page, which then submits the information back to a servlet and then receives a response back via JSON. The home page then proceeds to send the user to their profile page or alternatively displays an error (e.g., if username and password do not match).
$.ajax({
dataType: 'jsonp',
async: false,
url: loginLocation,
type: 'GET',
crossDomain: true,
cache: false,
xhrFields: crossDomain ? {
withCredentials: true
} : {},
data: ({'key1': value1, 'key2': value2, ..., 'keyN':'valueN'}),
success: function(data){
if (data && data.status && data.status == "success") {
window.location = profileLocation;
} else {
errorHandler();
}
},
error: errorHandler
});
I am looking to change this from a GET request to a POST in order to prevent arbitrary query strings being sent into the servlet. However, it appears that there are several considerations at play here with regards to how the solution ought to be laid out. It must:
use POST instead of GET
be a cross-domain request (the login page and the servlet are on different domains over both of which I have access/control)
use the withCredentials parameter (the login functionality relies on the JSESSIONID cookie so this parameter is required)
be compatible with IE8 and above
I have tried looking into cross-domain ajax requests that fit the above criteria, but the major sticking point seems to be the IE8/IE9 compatibility. Approaches such as easyXDM appear to be ambiguous as to support for these browsers (I have seen conflicting reports online as to how it works in IE8) and I don't want to run into the danger of realizing it won't work halfway through implementation.
So in short, is there a way to do cross-domain ajax requests using POST and with the withCredentials parameter, that is also compatible with IE8+? Is easyXDM an appropriate solution to this?
I was able to determine the solution to the above question by using the xdomain library (found at https://github.com/jpillora/xdomain) which overrides the request behavior to allow cross-domain ajax in IE8 and IE9. This involved setting up the proxy.html as shown in the example on the xdomain site as well as adding Access-Control-Allow-Origin and other related headers to the server response. This allows cross-domain ajax JSON POST requests using withCredentials in IE8+ per the criteria listed in the original post. It also allows cross-domain requests between HTTP and HTTPS.

Ajax post being aborted by firefox (not seen in Chrome or IE)

When using firefox, an ajax post request i have is being reported as aborted in firebug. The ajax post works fine in IE and Chrome. It is not a cross domain request. I tried looking at the issue using fiddler, and when fiddler is capturing web traffic (with options set to decrypt https) the post works. The post issue cannot be created in my local development environment, as all Firefox attempts successfully post the data I'm sending via ajax. Any idea why the post works while fiddler is running? It might give me some idea of how to get it working.
$.ajax({
type: 'POST',
url: '/Save',
data: JSON.stringify(dataset),
datatype: "html",
contentType: "application/json",
success: function (data, textStatus, jqXHR) {
//alert("success");
},
error: function (jqXHR, textStatus, errorThrown) {
//alert("error");
}
});
Also, this ajax request is called by a number of methods, and only when the largest of the datasets is sent does it fail.
Try only
async: false
in ajax option, I had the same problem.
I would start by explicitly setting (and changing) some of the basic ajax options:
cache: false,
timeout: 60000,
async: false
What type of content your server returning. JSON or HTML content. Are you using charset=utf-8 in server content. Make sure your server response must be in JSON contentType. Another guess remove datatype: "html" from your code. Try for your luck.
If your server returns json means, try below
$.ajax({
type: 'POST',
url: '/Save',
data: JSON.stringify(dataset),
datatype: "json",
contentType: "application/json",
success: function (data, textStatus, jqXHR) {
//alert("success");
},
error: function (jqXHR, textStatus, errorThrown) {
//alert("error");
}
});
datatype: "json", contentType: "application/json" makes sense
If you send this AJAX request from an event handler (example : click of a submit button), be sure to prevent the browser's default behavior (submitting the form), until you'll have 2 HTTP requests fired, with the first being aborted.
You can use e.preventDefault() to achieve this.
I just had this trouble on IE8.
Check the maximum post size setting on your server.
I also had similar issues and tried some of the ideas described above.
I finally fixed "aborted" state by :
adding e.preventDefault(); and return false; to buttons event handlers
adding datatype: "json", contentType: "application/json", to jQuery.ajax method params.
Thx to everyone for the clues.
This is either a cross domain issue or it is an issue with Firefox aborting your request because request is async. For cross domain you can check the origin of your request and what is allowed on webservice. You might have to read up on CORS.
If it is not cross domain then it is certainly a problem with request being async. Just change it to sync.
If you are using 2-way SSL auth on a CORS request, Firefox will abort your jQuery ajax requests by default. This is due to differing implementations of CORS in Firefox and Chrome. You can resolve this issue in your client code by adding withCredentials: true to your XHR instances. In jQuery, you can add this to the ajax call:
xhrFields: {
withCredentials: true
}
Check out these bug reports for more details:
Chrome sends TLS client certificates in CORS preflight, in violation of spec requirements
TLS handshake fails on CORS requests because no certificate is sent
I've also noticed that Firefox still absolutely refuses to send credentials on OPTIONS preflight requests, so you will need to configure your server to not require them (which seems crazy to me in a 2-way SSL scenario).

How do I make a Cross-Domain Request in Firefox?

I am using the following jQuery AJAX call to access a SOAP Web Service:
jQuery.ajax({
url: url,
type: "GET",
dataType: "jsonp text",
crossDomain :true,
data:"i="+'a'+"&j="+'b',
processData: false,
success: OnSuccess,
error: OnError
});
This code works fine in IE but it get an empty response in Firefox. On further searching it seems Firefox does not allow cross domain requests by default, or it processes the header information differently.
My application is on localhost:8081, and the WebService I want to consume is on localhost:8080. Is there any way I can allow Firefox to make a cross domain request?
See https://developer.mozilla.org/en-US/docs/HTTP_access_control
ya, This issue is resolved after I installed CORS add-on for firefox. But is there any other way, I can set the parameters using JQuery-ajax code?
you need send "Access-Control-####" headers same what in OPTIONS request response.

Access-Control-Allow-Origin Error Trying to GET json

I'm trying to utilize the Bing API to pull back spelling suggestions, but keep getting the below error:
XMLHttpRequest cannot load http://api.search.live.net/json.aspx?Appid=myIdWasHere&query=explotion&sources=spell. Origin http://myWebServerNameWasHere is not allowed by Access-Control-Allow-Origin
I read a couple posts that looked similar, then about CORS, but I'm still a bit fuzzy. What do I have wrong in the below code?
$.ajax({
type: 'GET',
url: 'http://api.search.live.net/json.aspx',
dataType: 'json',
data: {
Appid: '<myIdWasHere>',
query: 'explotion',
sources: 'spell'
},
beforeSend: function(xhr){
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
},
success: function(data) {
alert(data);
},
error: function(msg) {
alert(this.url + " -Failed"));
}
});
CORS (http://www.w3.org/TR/cors/) is a newish way of making cross-domain requests using XmlHttpRequest. Since you are making a request from your domain to api.search.live.net, it is considered a cross-domain request. CORS requires server-side support in order to work; specifically, Bing needs to include a special header that indicates that cross-domain requests are allowed.
My guess is that the Bing API does not allow cross-domain requests. In order to make a request, you should instead look into using JSON-P (http://en.wikipedia.org/wiki/JSON#JSONP). From their documentation, it looks like Bing does support JSON-P. Check out the "Callback Enumeration Example" section here:
http://msdn.microsoft.com/en-us/library/dd250846.aspx
Old post, but the Access-Control-Allow-Origin should be on the server not the client/calling domain.

Resources