Pre-flight OPTIONS request failing over HTTPS - ajax

A CORS POST request (AJAX) made by my client server (running on Apache # port 443) to my REST server (running on Tomcat # port 8443), fails to trigger when tried over HTTPS.
Please note that all the requests function properly without SSL.
I have already set the withCredentials: true options in the request fields. And my Tomcat server also takes care of the appropriate headers :
response.addHeader("Access-Control-Allow-Origin", "https://localhost");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Allow-Methods", "OPTIONS, POST");
I also tried using Curl, but the issue persisted over SSL. However, the Tomcat server responds to all my requests when tried directly over Postman/through the browser.
Could someone tell me what I'm missing out here?

I'm assuming this is an issue with the preflight request. There are two types of CORS requests: simple, and not-so-simple.
The simple kind is either a GET or POST with no custom headers whose content type is "text/plain".
The not-so-simple kind is any request using custom headers, utilising request methods other than POST or GET, and using different content body types. These requests will be "preflighted"; that is the browser will make a preflight request on the clients behalf in order to determine whether or not the server will allow this request. The preflight request uses the OPTIONS method. I'm willing to bet if you use something like Firebug to have a look what's going on you'll see something like this in the Net tab: "OPTIONS activity" with a status of "Aborted".
Unfortunately the preflight request doesn't pass the client certificate to the server which is why your request is failing to trigger. You need to disable two way SSL in order to get it working. In Apache you can try changing the SSLVerifyClient to:
SSLVerifyClient optional
I've used this before in order to get my cross domain AJAX calls working over HTTPS.
Good luck.

Related

What does "Response to preflight request doesn't pass access control check" mean?

I have receive the following response when trying to access an API via an ajax request in Chrome:
"Failed to load http://localhost:1880/api_resource: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:3000 is therefore not allowed access."
As you can see from the message, both client and API are running locally.
I understand that this situation relates to a CORS cross origin request. I see that there are similar questions about this on stack overflow, but from those answers I do not understand what the message is telling me and where it comes from.
Specifically I understand that the response header "Access-Control-Allow-Origin" must be set (typically to '*') to allow access to the API from a different domain to the one on which the API is being served. But the message seems to relate to the request and not the response, and as far as I am aware, no request ever reaches the API.
What is a preflight request and how is it failing?
As I now understand it, modern browsers will issue a 'preflight' request before the actual cross origin request. This preflight request uses the 'OPTIONS' HTTP verb along with the CORS headers Access-Control-Request-Method and Access-Control-Request-Headers to which it expects to see a response with valid Access-Control-Allow-Origin in the header that indicates that the server understands the CORS protocol and will allow the actual (GET/POST/PUT) request.
The message "Response to preflight request doesn't pass access control check" means that the browser did not see a valid "Access-Control-Allow-Origin" header in the Options response.
In my case this was because the server (implementing a REST API) was set up to respond correctly to PUT and POST requests but not setup to respond to OPTIONS requests with the CORS headers.
in my case the problem was for my website address, i'm calling all apis from the same server but i got this error.
my website address is sateh.ir
so im my ajax request i set the url: http://sateh.ir/api/...
after getting this error and working on it for some hours, i got that i had to set ajax url to: http://www.sateh.ir/api/...
i dont know why my website cant understand that i'm calling api from the same server if i dont put 'www', but that was my problem at all.

GET request from server and client

Lets say we have other domain with API for get user by ID
web.com/id=5
My server localhost:1337 do request on this API...
request.get(...web.com/id=5...)
And gets response with all data.
But GET ajax request from client browser with same localhost:1337 dont work like that.
I hear about cross-origin but why my server dont care?
In general, APIs allow Cross Domain requests. They do this by using this header:
Access-Control-Allow-Origin: *
This header works for most cases, but there are additional headers used when dealing with custom headers, or non get/post requests.

How to send the right Access-Control-Allow-Origin value for responses to cross-origin requests with credentials/cookies

I have a setup where a client application is running on a different domain (http://www.example.com) than the server application (http://www.example2.com). I've got the cross domain AJAX requests working except that I cannot figure out a way to send cookies with the request without having to add the Access-Control-Allow-Origin response header for each possible domain. Is there a way to set this up without having to specify a list of domains in that header? I'm aware of the security implications so I guess what I'm really asking is ... is there another framework separate from CORS that I can use which will allow this type of setup and at the same time allow any domain for the client application? I tried JSONP but that did not work out (could not send the cookie with the JSONP request). Is there something else I should try other than CORS and JSONP? Thanks.
EDIT: This is not a duplicate of the question mentioned in the duplicate notification. I'm already aware of the withCredentials flag. The problem is that I don't want to have to specify a list of domains in the CORS response header. I want something equivalent to setting that value to '*', but setting it to '*' is not allowed if sending a cross domain AJAX request that contains cookies.

Sencha Touch and CORS request not working

I'm trying to implement a login service on a Web app using Sencha Touch.
I already have a REST service working properly (I can test it using chomr extension Dev HTTP Client).
Now, the request is an Ajax request after doing some research, I've found out that cross-domain requests are protected, according to CORS.
I modified my Ajax client, adding:
useDefaultXhrHeader: false
when constructing the Ajax request, and I added to the headers:
Access-Control-Allow-Headers: x-requested-with
Access-Control-Allow-Origin: *
in my response.
Still using the Dev HTTP Client, I can now see my headers correctly set in the response.
But, in my app, I keep getting the error:
No 'Access-Control-Allow-Origin' header is present on the requested resource
If I use the --disable-web-security parameter when launching Chrome, everything works as it should, headers are sent (or at least, they are not blocked anymore by Chrome), but obviously, this is not the proper way to do it.
Can someone help me out on this?
Please follow the link http://enable-cors.org/server_apache.html and enable cors on your server. You client ajax request is correct but you still need enable cors on the server.

Why is ExtJS sending an OPTIONS request to the same domain?

I'm loading my script on a domain and sending some data with POST and the use of Ext.Ajax.request() to that same domain.
Somehow the dev-tools show me, that there is a failed OPTIONS request.
Request URL : myurl-internal.com:8090/some/rest/api.php
Request Headers
Access-Control-Request-Headers : origin, x-requested-with, content-type
Access-Control-Request-Method : POST
Origin : http://myurl-internal.com:8090
It's both HTTP and not HTTPS. Same port, same host ... I don't know why it's doing this.
The server can't handle such stuff and so the request fails and the whole system stops working.
It's not really specific to Ext JS -- see these related threads across other frameworks. It's the server properly enforcing the CORS standard:
for HTTP request methods that can cause side-effects on user data (in
particular, for HTTP methods other than GET, or for POST usage with
certain MIME types), the specification mandates that browsers
“preflight” the request, soliciting supported methods from the server
with an HTTP OPTIONS request header, and then, upon “approval” from
the server, sending the actual request with the actual HTTP request
method.
If you're going to use CORS, you need to be able to either properly handle or ignore these requests on the server. Ext JS itself doesn't care about the OPTIONS requests -- you'll receive the responses as expected, but unless you do something with them they'll just be ignored (assuming the server actually allows whatever you're trying to do).
If you are NOT intending to use CORS (which sounds like you aren't purposefully going cross-domain) then you need to figure out why the server thinks the originating domain is different (I'm not sure about that). You could also bypass CORS altogether by using JsonP (via Ext's JsonP proxy).
Use relative url instead of absolute, then you will get expected result.
use before request
Ext.Ajax.useDefaultXhrHeader = false

Resources