Getting around CORS by forwarding from the back-end - spring

I'm implementing an internet speed test in my Angular app, and I'm using fast.com to test the speeds. The problem is that it takes 2 calls: The first call to https://api.fast.com/netflix/speedtest/v2 returns 5 URLs that should be called. Each of these URLs are chosen based on their CDN geolocation to you the client, and availability.
Unfortunately, this call does not return CORS headers, but the subsequent 5 URLs do. I've gotten around this by having my back-end make the first call, but the URLs will always be generated based on the location of my server.
Is there a way to forward a request from the back-end so that the service sees the original IP address? Or is there a fast.com param/header I can include from my back-end call?

You could attempt to use the X-Forwarded-For header, which is the de-facto standard header for doing requests like this.
(I'm not 100% sure if Fast.com supports this, but this might be worth a try)

Related

Can nginx be configured to allow a path like /api to pass through, and add a header to the request

I am using NGINX as my web server for html/js/css files and my web app UI. It is a single page app that uses AJAX requests to a back end JEtty server. Previously I deployed everything in Jetty and ajax calls worked fine. In separating the back end from the web UI tier, I am now trying to figure out how to configure NGINX to allow AJAX requests to pass through to Jetty. But, I ALSO want to prevent someone from watching network traffic and seeing the ajax calls my app makes, then scripting those themselves. To do this, I believe if I can configure nginx to ADD a custom header to the requests as they pass through (is this even possible?) I could then only accept requests with those headers at my Jetty API level.
If that is possible, is it the right way to handle this so that outsiders can't get in to my back end API? Is there a way they could figure out that my nginx server is adding a header short of breaking in to my server and figuring out the configuration?
If your application calls your api via Ajax on the client there's nothing you can do to stop someone from calling it directly (assuming they otherwise have access to the page). At the end of the day, an Ajax request is just a request made from the client in JS. Now, there are lots of stupid ways to make it more difficult, but, if anyone really wants to call your api directly, they can.
If you're just talking about only allowing access through nginx (or specifically your /api location block), just bind jetty to localhost only.

Hosting two websites on same domain

I have two apps named opentripplanner-webapp and opentripplanner-api-webapp. I had successfully deployed them on local tomcat server. Apps has url as http://localhost:8080/opentripplanner-webapp and http://localhost:8080/opentripplanner-api-webapp. When i deployed apps on appfog , they give me different domains for both apps. The problems is that my apps use ajax request and responses which does not work on cross domains. I am searching for two days to find any solution but didn't find any suitable solution. Kindly guide me.
Thankss
Here's a couple of options for you:
Use JSONP (JSON with Padding). You would have to write your api so it supports this protocol, but it shouldn't prove too difficult.
Create both opentripplanner-webapp and opentripplanner-api-webapp so they support Cross Origin Resource Sharing. This means that your webapp sends an Origin header in the request, and the server responds with an Access-Control-Allow-Origin header, and if they match, the browser accepts the request. This is however not supported by all browsers, although most modern browsers do.
Use a proxy servlet in your opentripplanner-webapp that proxy requests to your API. You can "mount" this servlet at e.g. /api in the webapp, and it will forward all requests to opentripplanner-api-webapp internally. So you would send your AJAX requests to http://webappserver/api instead of http://apiserver. For the browser, this will look like an ordinary same origin request. This will work in all browsers, but might require some more setup.

How to perform cross-site ajax request?

Browsers don't allow cross-site AJAX calls (it's a security restriction).
Is there any possible solution ?
EDIT
I control only the caller website
If you control both parties then there a lot of options. Such as JSONP, or modifying header responses of the remote website. Unfortunately, JSONP only works if the remote website supports it. You can't force a JSONP call to a website that doesn't already support it.
However, as you have said, you only control the source website. You cannot hack the browser around this restriction for obvious reasons. You do have a third option which is creating a back-end proxy. You can use Apache and mod_rewrite to create a proxy. Here is on how to do this or this link which is more detailed.
For example
ProxyPass /api/gtalkbots http://gtalkbots.com/reverse-proxy-data.php
ProxyPassReverse /api/gtalkbots http://gtalkbots.com/reverse-proxy-data.php
Creates a proxy at /api/gtalkbots which will returns the repose from gtalkbots.com
Your best solution is to use JSONP calls.
function jsonp(url, params, callback){
var script = document.createElement("script");
script.setAttribute("src", url+'?'+params+'&callback='+callback);
script.setAttribute("type","text/javascript");
document.body.appendChild(script);
}
function doit(data){
alert(data);
}
jsonp('http://domain.com', 'foo=bar', 'doit');
In the opposite side, the website you're contacting must be able to return a JSONP formatted response in order for this to work.
There are 2 ways to do this, depending on whether the callee will ship out JSONP or not:
1. If you can, use JSONP
JSONP is a way to bypass the cross domain policy by returning a function call, rather than a naked JSON object. The P stands for padding, essentially just the part that calls the function.
For this to work, the callee needs to return JSONP.
Regular JSON looks like this:
{a: 12, b: 15}
JSONP looks like this:
callback({a: 12, b: 15});
When the AJAX request completes, the callback function (which you define in your own code) will be executed and the JSON data passed to it as an object, thus bypassing the cross domain policy.
2. If JSONP is not supported, mirror the request through your own server
The second option is to pipe data through your own server. Your JavaScript makes a request from your server, and the server then mirrors that request to the remote server and pings back the result.
Since the AJAX request is now made to your own server you won't run afoul of the cross domain policy.
There are two downsides to this approach:
Two requests are now required which will slow the response time a little, though probably not much as server to server communication will probably be via a fat pipe.
Since all requests now originate from your server you may have problems with IP based rate limits. This is the case with Twitter API calls. You may be able to mitigate against this by caching results.

Cannot make ajax call between servers that differ only in port in HTML5/jQuery/Chrome stack

The parts
I am developing against two Pylons servers and testing locally. One server is on port 5000 and is the called server. The other is on port 7000. The latter creates a cookie that specifies the same domain as used by the former server. Essentially, the first server uses credentials provided by the second server to impersonate the user.
The first server expects to find an auth token (a cookie, really) in its response.environ at run time. When I authenticate on the server on port 7000 and browser to a service on port 5000, the latter server uses the cookie created by the former and the app works.
The fly in the ointment is that the first server creates an HTML5 app that uses an ajax call to the second server, and I cannot get the cookie to be included in the ajax call. I believe that Chrome (the browser we are using/requiring for HTML5 support reasons) refuses to send the cookie for cross domain reasons: going from foo.net:7000 to foo.net:5000 is considered cross domain.
Oh, and the ajax call is through jQuery.
The question
Is there any way to make an ajax call from an HTML5 app created on a port in the same domain to a server in the same domain but a different port?
What I've tried or discard out of hand
I do not believe I can use dynamic script tag insertion because I am making the call from javascript and the HTML is generated on the client at runtime from other javascript. At least, I don't think that is a desirable solution.
I don't believe Access-Control-Allow-* is applicable because I am going from client to server, not the other way.
I've seen this on jQuery and ports in ajax calls. I've seen this, too.
I know about the same-origin policy.
And this does not work.
Agree with Michael that the simplest solution is JSONP. But even in JSONP you need to configure your server such that it supports JSONP. Many Servers deny this to keep their data secure and sound. JSONP expect your server to send data in the format that can be evaluated as the valid JSON. But its not the case in every JSONP Request and response. So, just watch out for that.
The absolutely simplest solution to this is to use JSON/P. I wish there were an easier, softer way to accomplish this, but I certainly haven't found one.

HTTP digest authentication for AJAX requests

Hey SO, so I've got an API I'm making calls to in a browser application. Said API lives on a server that requires whitelisting and HTTP Digest Authentication.
To meet the whitelisting requirement, I'm running all API calls through a proxy, which is whitelisted. The calls are originating from an iFrame, currently populated by an index.html file.
What I need to know is how I can authenticate via HTTP Digest in the background. Most of the resources I can find online seem to involve the original HTTP Digest Authentication setup, but what I'm looking to do is automate login.
Despite the non-secretive subject matter, it is somehow critical that I keep the digest parameters obfuscated from users. Perhaps I could change the served file to index.php and then somehow set the magic headers? Even then, if the calls made via XHR, would the index.php headers authenticate the separate request?
Overall, I'm just lost, and the API developers in question are not exactly responsive, so thought I'd turn here.
It appears that in the end, this was not possible. I had to switch to building a thin back-end to route requests through.

Resources