I have been racking my brains for a simple solution. Lets say, I have 10 API endpoints in my Node JS application.
I have already allowed 3 of them to be public, the remaining 4 have JWT based authentication
Now I have 3 more routes, which will not have JWT and I need to only allow Server side calls. No browser or curl or postman, should be able to call them. How do I identify from the request object that it is originating from a server?
Or to put it in another way, how to I reject all cross origin calls to my api? As server side does not fall in CORS, they should filter through
----- EDIT -----
I recently came across a service that uses User Agent header to block server side calls. Can i enforce User Agent header for my service and ensure that the header does not have browser agents. This can be hoodwinked easily, but as a theoretical solution, what would be the nodejs interceptor that discards requests whose user agent refers to a browser agent?
You should use a similar authentication/authorization as for the routes that have JWT authentication from the clients.
This means that the caller service should also authenticate using a JWT token, having a special role
of service
or something like that (this is 100% your decision on what convention you choose). That token should be signed by the caller and verified by the receiving microservice.
This solution has the advantage that it does not depends on the infrastructure, it works the same no matter where the services are deployed.
You can use the express-ipfilter package and only apply it to certain routes you want to protect:
const express = require('express'),
ipfilter = require('express-ipfilter').IpFilter;
// Whitelist the following IPs
const ips = ['127.0.0.1'];
// Create the route
app.get("/securePath", ipfilter(ips, {mode: 'allow'}), (req, res) => {
// only requests from 127.0.0.1 (localhost/loopback) can get here
});
app.get("/openPath", (req, res) => {
// all requests can get here
});
app.listen(3000);
If you are using Node behind a proxy, you may need to configure the proxy to set a header with the actual IP and then pass the ipfilter
function a function in the detectIp
property to the second parameter.
Let's say you are using nginx and have it configured to send the original IP through the x-Real-IP
header, you can pass this function to ipfilter
:
const express = require('express'),
ipfilter = require('express-ipfilter').IpFilter,
ips = ['127.0.0.1'];
app.get("/securePath", ipfilter(ips, {mode: 'allow', detectIp: getIp}), (req, res) => {
// only requests from 127.0.0.1 (localhost/loopback) that go through the proxy can get here.
});
app.get("/openPath", (req, res) => {
// all requests can get here
});
app.listen(3000);
function getIp(req) { return req.headers["X-Real-IP"] }
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