A simple proxy to circumvent the SOP

A handy Node.js script that helps with front-end development to a remote server without the CORS headers set

Motivation

Often during frontend-only development there is a backend server accessible without setting the CORS headers. The common solution would be to fire up the backend on my computer too and it makes the API to be on the same host as the code I’m working. The bad solution would be to set the CORS headers in production even they are not needed, effectively opening an attack vector. The solution I came up with is a simple proxy that serves static files from the file system and proxies some paths to the remote API server. Since Same Origin Policy only affects browsers, making the call from the server-side possible, and it effectively brings everything to the same domain.

The proxy script

Dependencies

For this proxy, I’ll be using Node.js, as it provides very easy dependency management with a simple file. These dependencies are Express and Request. The other important part in package.json is the main property that sets the main script.

{
  "name": "a_simple_proxy_to_circumvent_the_sop",
  "description": "Proxy+Express",
  "author": "gsashee@gmail.com",
  "dependencies": {
    "express": "4.13.x",
    "request": "2.58.x"
  },
  "main":"server.js"
}

Then with a simple npm install, both dependencies are downloaded and ready to roll.

The script

The script is very simple. It fires up an Express server that serves the static files from the fs, and adds a route that forwards to the predefined API URL. The complete source is as follows:

var express = require('express');  
var request = require('request');

// Parameters
// You can use a shorthand for multiple API endpoints: /api|/other_api
var paths='/api';
var apiServerHost = 'http://echo.httpkit.com';

var app = express();  
app.use(paths, function(req, res) {
  var url = apiServerHost + req.baseUrl + req.url;
  console.log('piped: '+req.baseUrl + req.url);
  req.pipe(request(url)).pipe(res);
});

app.use(express.static('.'));

app.listen(process.env.PORT || 8080);

For the paths multiple values can be added, delimited with a pipe (|).

Start it with a simple npm start and it will be listening on http://localhost:8080 . Also you don’t need to restart it when you make changes to the files, making front-end development easier.

For an added benefit, it supports Heroku, so just create a new app there and push your code, and it makes an instant preview server.

Conclusion

This proxy script proved to be very useful in some situations. It is in my ever accumulating development tools collection. I hope you find it useful and saves some coding next time.

28 July 2015

Interesting article?

Get hand-crafted emails on new content!