Securing Nodejs express API - node.js

I am making a very basic REST API using Express 4 (express.Router). How can I secure this API in a simple way?
I do not need to authenticate individual users so most of the strategies that I have found seem like overkill. I am just trying to moderately secure the API so I am hopefully the only one using it. Not sure what strategy I can use to pass something from the client to identify myself. Thanks!
I will be accessing this API from a web page as well as mobile client (with Ionic) and hosting the app on Google Clouds App Engine.

You could use a header or a query string to authenticate. For example, setup a middleware on Express to check if the header X-TOKEN contains a string of your choice.
Here's a code which you can use to do that:
function checkAuthHeader (req, res, next) {
let token = req.headers['X-TOKEN'];
if (token && token == "RANDOM_GENERATED_STRING") {
next();
} else {
res.status(403).end('Unauthorized.')
}
}
Then you can use this function as a middleware like this (make sure you place it before declaring your routes):
app.use(checkAuthHeader)
You should be using environmental variables instead of a hard-coded string as well. I just used a hard coded one for demonstration.

Related

Creating a Node.js REST API using Firebase Cloud Functions, without Express?

I am working to create a serverless REST API via Firebase Cloud Functions, which seems to work well but the examples and documentation all seem to use a monolithic solution, since they use the Express framework and essentially map the root http request to the Express app, then let it handle the routing. I understand that this is because the Firebase Hosting platform does not have the ability to handle http verbs.
My expectation was that a serverless / FaaS approach would have a function for each endpoint, making for easy updates in future since there's no need to update the whole app, just that single service - i.e. a more functional approach.
What am I missing here? Why is the approach to use a single function to contain an express app? Doesn't this defeat the purpose of a serverless / Cloud Functions approach? And is there any other way of doing this?
The documentation shows how to create an endpoint without the help of an Express app, router, or middleware:
exports.date = functions.https.onRequest((req, res) => {
// ...
});
All you have to do is arrange to send a response with res.send(...) or similar.

Microservices API Authentication with API Gateway in NodeJS/Express

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.";
}
});

Best way to handle API calls from frontend

Okay, so atm i have a frontend application built with Nuxt JS using Axios to do requests to my REST API(separate).
If a user does a search on the website the API URL is visible in XMLHttprequests so everyone could use the API if they want to.
What is the best way of making it so that only users that search through my website gets access to the API and people that just directly to the URL gets denied. I suppose using some sort of token system, but what is the best way to do it? JWT? (Users never log in so there is no "authentication")
Thanks!
IMO, you CANNOT block other illegal clients accessing your
backend as you describe that the official client and other illegal have the same knowledge about your backend.
But you can make it harder for illegal clients to accessing your backend through some approach such as POST all requests, special keys in header, 30-minutes-changed token in header and server-side API throttling by client IP.
If the security of the search API is really important, authenticate it by login; if not, just let it go since it is not in your critical path. Let's focus on other important things.
I'm in the same "boat" and my current setup is actually in VueJs but before even come to StackOverflow I developed a way to actually, the frontend calls the server and then the server calls the API, so in the browser, you will only see calls to the server layer that, the only constraint is that the call must come from the same hostname.
backend is handled with expressJs and frontend with VueJs
// protect /api calls to only be originated from 'process.env.API_ALLOW_HOST'
app.use(api.allowOnlySameDomainRequests());
...
const allowHostname = process.env.API_ALLOW_HOST ||'localhost';
exports.api = {
...
allowOnlySameDomainRequests: (req, res, next) => {
if(req.url.startsWith('/api') && req.hostname === allowHostname) {
// an /api call, only if request is the same
return next();
} else if (!req.url.startsWith('/api')) {
// not an /api call
return next();
}
return res.redirect('/error?code=401');
},
...
};
In our case, we use Oauth2 (Google sign through passportJs) to log in the user, I always have a user id that was given by the OAuth2 successful redirect and that user id is passed to the API in a header, together with the apikey... in the server I check for that userid permissions and I allow or not the action to be executed.
But even I was trying to find something better. I've seen several javascript frontend apps using calls to their backend but they use Bearer tokens.
As a curious user, you would see the paths to all the API and how they are composed, but in my case, you only see calls to the expressJs backend, and only there I forward to the real API... I don't know if that's just "more work", but seemed a bit more "secure" to approach the problem this way.

OWIN static files security

I'm building a SPA that will be sitting in a WebAPI/OWIN app (that will be hosted in IIS) that currently has no MVC components what so ever and the / route will just be index.html.
The whole site will need you to log into Azure AD before you can do anything and we'll then pass a bearer token to the WebAPI calls that are made.
How do you make every request to a static file (or at least, every HTML file) require you to be logged in?
I will tell you how I did it, and how it works for me.
I am using windows authentication, and here is how I configured it:
OwinHttpListener listener = appBuilder.Properties[typeof(OwinHttpListener).FullName] as OwinHttpListener;
listener.Listener.AuthenticationSchemes = AuthenticationSchemes.IntegratedWindowsAuthentication;
Then, according to this stackoverflow answer, put the following code between your auth middleware (or the auth code like the above code) and the components you want to protect. It will check to ensure that each request is authenticated.
app.Use(async (context, next) =>
{
var user = context.Authentication.User;
if (user == null || user.Identity == null || !user.Identity.IsAuthenticated)
{
context.Authentication.Challenge();
return;
}
await next();
});
I haven't tested this, but it is what I'd try first so I'm hoping it puts you on the right track.
Configure your app so OWIN is serving all static files via the StaticFilesMiddleware. This article talks about how to do that
Before you register the static file middleware (with the .UseStaticFiles extension method) create and register your own RequireAuthenticationMiddleware that checks if the request is authenticated and if it isn't returns the appropriate response (401, 403 or whatever). You'll want to register this RequireAuthenticationMiddleware after you configure the OWIN Auth middleware so that the auth details are in the OWIN context.
I haven't attempted that using OWIN middleware yet, but you could always fall back to using a HTTP module that checks for the presence of your auth cookie or bearer token?

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

Resources