I'm going through this tutorial for building a node api:
http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4
They go through how to test post requests with getpostman.com.
However - I don't want my application to respond to post requests from different domains. I only want it to respond to post requests from Rails on my domain (not browser). How do I stop accepting these requests from foreign origins, yet allow the requests from my rails server?
I tried middleware like the below which I found from this link. But didn't work. This has to be easy. Any clues?
router.all('/', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "https://www.example.com");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "POST GET");
res.header("X-Frame-Options", "ALLOWALL");
res.header("Access-Control-Allow-Credentials", "true");
next();
});
You can check where a request came from by checking the client's IP as described here. You can then compare it to a list of allowed addresses or do a reverse DNS lookup to check against a domain. The latter approach should be implemented carefully and it might be better to first resolve the allowed domains and check against a set of static IP addresses.
Here is a small module which exports a middleware which will do exactly that (not even tested once).
// allowed is an array of allowed hosts
// readyCb is an optional function that will be called
// once all host names have been resolved
module.exports = function(allowed, readyCb) {
// Resolve all domains
var ips = [];
var remaining = allowed.length;
allowed.forEach(function(host) {
if(/^[.0-9]+$/.test(host)) {
// Should be an IP address
ips.push(host);
remaining--;
if(!remaining && readyCb) readyCb();
} else {
// Resolve the host name
// Adapt this if you want IPv6 support
require('dns').resolve(host, 'A', function(err, addresses) {
remaining--;
if(!err) {
addresses.forEach(function(ip) { ips.push(ip); });
} else {
// Handle the error, either using an additional callback
// or by collecting all errors and submitting them to
// readyCb
}
if(!remaining && readyCb) readyCb();
});
}
});
return function(req, res, next) {
var clientIp = req.ip;
// Check if the address is allowed
if(ips.indexOf(clientIp) == -1) {
res.end(403, 'Remote host is not allowed to use the API');
} else {
next();
}
};
};
Use a middleware like this:
var url = require('url'); // standard node module
function(req, res, next) {
var ref = req.headers.referer;
if(ref) {
// We got a referer
var u = url.parse(ref);
if(u && u.hostname === 'myhost.com') {
// Correct host, process the request
return next();
}
}
// Send some kind of error
res.send(403, 'Invalid origin');
}
Please note that the referer header might be unavailable. Adapt the above snippet to react to such situations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With