Microservices API Authentication with API Gateway in NodeJS/Express - node.js

I'm creating a Microservice architecture using Node JS and Express. I know that one of the main features of Microservices are a service oriented architecture where teams can design, develop and ship their applications independently. So in my design I think that each microservice offers their APIs and they communicate between each other with the API in this way each Microservice is independent and have it's own life waiting for request.
I am writing this question because I have several doubts about
authentication and communication between microservices.
For the autentication I have made some test with JWT to authenticate the API of a Microservice and all works fine, this is an example of express middleware for authentication:
const tokenCheck = (req, res, next) => {
let token = getToken(req);
if (token) {
jwt.verify(token, "password, (err, decoded) => {
if (err) {
throw "Failed to authenticate token.";
} else {
req.user = decoded;
next();
}
});
} else {
throw "No token provided.";
}
};
Used in this way:
router.get("/", tokenCheck, Controller.get);
So each route is protected with a layer of autentication.
Instead about communication between microservices I read the best way is to use an API Gateway and I found this library to do it, furthermore i read that it's better to add the authentication middleware inside the API Gateway because if you re-implement these things in each single microservice, you are duplicating the code at first, but more importantly you have two different pieces of software to maintain.
Now my question are two:
1) Is right use an API gateway like this to make communication between microservices?
2) If I move the authentication middleware from the microservices to the API Gateway I have to remove the middleware from the API routes and in this way the API will be unprotected if someone other than the gateway make requests and I think this is wrong because anyone can call that routes, instead if I mantain the middleware also is the mircorservice the code is duplicated, can anyone tell me what is the right way to do it?

I have been working on Node.js from past couple of years and here is my understanding, hope this helps you clear your thoughts.
The answer to your question:
Let me explain to you the work of both the parts you have stated in the question.
http-proxy-middleware
Proxy: In simple words, the proxy means duplicate clone to turn your traffic too.
Read more: What is the proxy server?
Your custome middleware
Your custom middleware is the project specific code to check if all the requests are authenticated.
It would check if the request has a token and if the token is valid.
Conclusion:
You need your custom middleware compulsorily. Another one (http-proxy-middleware
) is optional.
Update:
Now my question are two:
Is right use an API gateway like this to make communication between
microservices?
Answer: No, it is not the right way.
If I move the authentication middleware from the microservices to
the API Gateway I have to remove the middleware from the API routes
and in this way the API will be unprotected if someone other than the
gateway make requests and I think this is wrong because anyone can
call that routes, instead if I mantain the middleware also is the
mircorservice the code is duplicated, can anyone tell me what is the
right way to do it?
For this, you can impose the authentication middleware on app so that all the routes execute the middleware.
Update your server code.
// Init App
const App = Express();
// Authentication code
App.use((req, res, next) => {
let token = getToken(req);
if (token) {
jwt.verify(token, password, (err, decoded) => {
if (err) {
throw "Failed to authenticate token.";
} else {
req.user = decoded;
next();
}
});
} else {
throw "No token provided.";
}
});

Related

Build a basic authentication for rest api in node.js

var auth = "116asd1f2341dfas2f"
//this is executed always before somone calls a request
app.use(function (req, res, next) {
var header=req.headers['authorization']; // get the header
if(header != auth)
{
res.status(401) // HTTP status 404: NotFound
.send('401 Unauthorized');
return
}
next();
});
Is this a safe way to protect an API? I am new to node.js
No, absolutely not. You have written a basic middleware that might offer some protection but isn't remotely secure.
There are a lot of things that go into ensuring the protection of an API. I would suggest you learn more about middlewares, token-based authentication and how does it work (JWT AUTHENTICATION is quite popular with node.js), Passport Authentication strategies etc.
We can't write the code for you but can surely guide you to correct way of doing things. There are a lot of excellent tutorials out there that can surely help you.
Remember, doing it yourself is the only way to learn.

How to secure an open REST API from abuse in Node.js?

For example, I have a REST api endpoint written in Node.js. It can be accessed from a webpage for non-technical users, and it can also be accessed through command line using the curl command. It doesn't require any credentials to access it because it is intended to be open for anyone to access it. The problem I am trying to solve is how can I prevent someone maliciously access this REST API endpoint, for example pinging this api endpoint over and over again, or how to prevent ddos attacks.
Not necessary a programming question, let me know if there is a better place to ask this.
Setup Rate Limiting if you cant have an auth on it.
You can use this if you are using express https://www.npmjs.com/package/express-rate-limit
Preventing DDOS is not that easy without using solutions like CloudFlare.
To secure your REST api, you can use middleware if you use express
const checkAuth = (req, res, next) => {
// logic for checking auth
if (authorized) {
return next();
}
res.status(401).send('NEED AUTH');
};
router.post('/login', checkAuth, (req, res, next) => {
// actual logic for login
});
Update: regarding #Akarsh's answer,
you can use multiple middleware before actual logic. For example, one for auth check, and one for rate limit
router.post('/logic', checkAuth, rateLimit, (req, res, next) => {});
You say you want it to be open, but then you say you want it to be sort of open!
Throttling / auth tokens. Choose at least one, pref both.
Pinging and DOS attacks are different and have nothing to do with your API as such. Unless your info is valueable / highly competitive, something as simple as IP banning will go a long way.

Implement an authorization layer for your restify API endpoints

I am pretty new to restify and nodejs in general. I am attempting to build a rest api using restify and nodejs, and I need to implement a token-based authentication layer, or middleware if you will. On login, I generate a jwt token, which I save to a database, and I would like to validate the users token before allowing them to access particular endpoints. I have found a lot of information on how to do this using the Express framework, similar to this example below
function middlewareHandler(req, res, next) {
console.log("execute middle ware");
next();
}
app.get('/', middlewareHandler, function (req, res) {
console.log("end middleware function");
res.send("page render finished");
});
but so far I haven't been able to find anything similar for Restify.
Can anyone please provide me some guidance on how to do this?

What's the better way of implementing security with MEAN.js

I'm working with mean.js, and I have a little doubt about authentication and authorization here...
MEAN.js come with a out of the box passport.js implementation that seems to be working good enough for me just to know when a user is logged in. But at the moment of authorization some question pop up in my mind.. doing my research I reach some answers and I don’t know what is the best way of implementing security API calls in my app.
So far, I'm taking this solution:
Using express.all() function to set in one file all my authorization functions ( I guess it is a good practice right ? ).. creating a file with the following code example:
'use strict';
var passport = require('passport');
module.exports = function(app) {
app.route('/private/p/*').all(function(req, res, next){
if(!req.isAuthenticated()){
res.send(401);
}else{
next();
}
});
app.route('/private/byRoles/*').all(function(req, res, next){
if(!req.isAuthenticated()){
res.send(401);
}else{
var urlRoles = ['admin', 'godlike'];
// ROLE LOGICS THAT ARE GOING TO BE ADDED TO MY USER
// GETTING MY USER ID BY THE DE-SERIALIZE PASSPORT FUNCTION AND GETTING MY
// MONGO MODEL FOR MY USER, WITH THE INFO OF ROLES IN THERE AND DOING
// SOME LOGICS HERE ABOUT THE ROLES AND URL PATTERN.
if ( hasRole(urlRoles, user.roles)){
next();
}else{
res.send(401);
}
}
});
};
So far this is the solution that I'm planning to implement, but I would like to be sure of what I'm doing here... is there a better way of implementing authorization in mean.js ? Is this authorization middle-ware wrong implemented with passport? I don't sure if is necessary to implement another strategy to this.. or if this implementation has a security lack ( sure it has to ).. is better to use Oauth or using api token ??? what should be the architecture to secure an app made in MEAN.js supporting roles and permissions ?? also in the future I would need to secure my socket.. I was looking at passport-socketio.. but not sure if is there a better solution.
I use JWT's for my angular apps. There are many articles out there about the benefits for using tokens instead of sessions or cookies Cookies vs Tokens. Getting auth right with Angular.JS.
You can do everything you want with JWT, roles for backend and frontend, securing sockets is also possible and there are packages for this functionality. You do not need passport if you using tokens. You check the the credentials one time and store the token in the browsers local storage. There are many packages for express and JWT Express-JWT
For a closer look at JWT jwt.io

Authenticate before calling route controller

I'm working on an API using restify. There will be a dozen or more endpoints and each one requires authentication. The API will be stateless, so each API request, regardless of endpoint, will pass credentials.
What I'd like to do, if possible, is to authenticate before negotiating the route. Otherwise, if I have a route:
server.get('/activities', activities.index);
Then, within activities.index (and every other routing method), I have to duplicate the following:
var user = require('../models/user')(server);
user.authenticate(req.authorization, function(err, user) {
...
// Do the real activities-related stuff.
});
This is one of those things where it feels like there must be a better way of doing it, but I don't know what it is.
Anyone have any thoughts?
So you can register handlers to be ran before every route is ran.
http://mcavage.me/node-restify/#Common-handlers:-server.use()
server.use(function(req, res, next){
//do authentication here
if(authenticated){
return next();
}
else{
res.send({auth:false});
})
So when you use server.use when the user asks for /activites it will run all of the server.use you created in the order you created them before running the code for the route.

Resources