express-jwt handling specific secret passphrase by routes - node.js

Here is my use case.
In my express app using express-jwt module, I have 2 mains routes. I would like to secure my routes with 2 distincts passphrase.
app.use('/api/v1/admin', jwt({secret: "blabla1"}).unless({path:['/api/v1/admin/login']}));
app.use('/api/v1', jwt({secret: "blabla2"}).unless({path: ['/api/v1/login']}));
In this case, it doesn't work as I was expecting to...
Is there a way to achieve this in only one express app ?
Thanks in advance for your helps guys!

Your syntax is a little off, what you are doing above is setting the secret for the whole app. If you wanted to protect a certain route you could do something like below.
app.all('/api/v1', jwt({secret: "blabla2"}).unless({path: ['/api/v1/login']}));
app.all('/api/v1/admin', jwt({secret: "blabla1"}).unless({path:['/api/v1/admin/login']}));
The above code allows you define different secrets for a particular route. The call to app.all catches every type of HTTP call.

Related

Issues with new express-openid-connect package

I have been trying to use express-openid-connect for the last few days with no success. I am able to get the flow to work when hard coding my params. However, my goal is to be able to dynamically call auth() depending on the user being logged in. My initial attempt included calling
app.use(auth(functionThatGetsParams()));
Using the approach above, express complains that secret is required. For some reason, the auth call is getting called before anything else is resolved.
I also tried doing a few different ways,
app.use((req,res, next)=> process.env.secret = 'hello');
app.use(auth({secret: process.env.secret}));
The example above also returns the secret issue. However, setting process.env.secret outside of app.use, works fine.
My issue seems to be related to the things I do in the app.use block. The approach I am looking to use is have a call that resolves who my user is and based off of that gets the right settings.
app.use(ConnectionResolver.resolve);
I use a call similar to the above which is basically a handler that does some async stuff to get the client info and right settings then ends with next().
I would expect that then calling
app.use(auth(ConnectionManager.getAuthSettings()));
Would return the auth settings I need, but when I debug, it looks like this line gets called before anything else, so then secret is missing as the error says.
One other option I believe I may have seen online is creating a list of auth calls for each client, which I can then use for authentication, but I have not seen any examples of how that works.
Does anyone have any ideas on how this might be possible? The environment I am in is multi tenant. So I need to be able to dynamically use a certain auth config depending on the user making the call.
Any help would be greatly appreciated.
You are misunderstanding the concept of middleware.
the auth function, is a middleware factory function, it gets a set of options and returns a middleware function based on those options.
The function passed to the use method of the express app, will execute only when an incoming request will arrive.
When you do app.use(auth(getParams())) what happens is that when your server is starting, it will call getParams function, pass the result to auth function which in turn will return the auth middleware function that will be passed to the app.use function.
Once a request will arrive, the auth middleware (the one returned by the auth factory function) will execute.
You don't need to use auth conditionally. You should set it up, and then you can use the requiresAuth middleware provided by express-openid-connect package to protect your paths that requires authorization/authentication.
If your secret is loading asynchronically, wrap your entire express app setup in a bootstrap function, load your secret and only then call the server bootstrap function.
async function loadSecret() {
//load secret from external source
}
function bootstrapServer(secret) {
const app = express()
app.use(auth({ ..., secert }))
app.get('protected', requiresAuth(), (req, res) => {
// your protected route, will automatically return 401 if not authenticated
})
app.get('non-protected', (req, res) => {
// This route will be open to all without authentication
})
}

Express Middleware

I'm a beginner in Express framework and having some difficulty with the code flow. I have following code in app.js
app.use('/', index);
app.use('/login', login);
app.use(require('./routes/authenticate_user'))
app.use('/user', userDetails);
Problem is that If a user enters an invalid route suppose '/wrong' then my middleware sends the response for that instead of app throwing 404 Not found. Is there something I'm missing?(looks obvious). Thanks for any help.
There are a couple choices for how/where you run the authentication middleware.
1) You can run it immediately after any non-authenticated routes have been defined. This will give you a non-auth error for any route, whether it's a real route or not other than the few routes that the user is allowed to go to without authentication.
2) You can manually add the middleware to each defined route that is supposed to have authentication such as:
app.get('/something', yourAuthMiddleware, yourRouteHandler);
This will run the auth check only on routes that are actually defined. This allows you to give a 404 rather than an auth error for routes that are not defined.
The advantage of the first option (which is essentially how you have it now) is that a non-authenticated user doesn't even get to find out which routes are defined or not. If they're not authenticated, they don't get in at all except to the couple of routes that they are allowed to. In my opinion, this is the right design.
The second option will let you give a 404 for a route that isn't defined, but it requires manually adding auth to each route or each router that you define that needs auth. This allows a non-authenticated user to find out which routes are defined and which ones are not.

Implementing Passport Local Authentication in Backend

I am trying to implement the passport local authentication in my backend. It is a todo app which is built with the help of the MEAN stack. Unfortunately, I am facing some problems implementing it. The folder structure is
In Controllers folder, the controllers for the various routes are present.
In routes folder, the file "api.route.js" contains the main route. I want to implement authentication here such that no further routes can be accessed if the user is not autheticated.
In the api subfolder, the different routes are configured.
In the config subfolder, the passport local strategy is defined.
Another new problem I have noticed is that the routes after todo are not detected.
Example : localhost:3000/api/todos
localhost :3000/api/todos/login
route does not work. It says Error 404. Every other sub routes are the same. Any help which will help me to implement will be appreciated. The github profile for this project is :
https://github.com/AritraWork97/TODO-FULLSTACK
The main folder is Todo Backend, it contains the backend code
To, protect routes in back-end I think express-jwt will be handy.
Initialize it like this,
const jwt = require("express-jwt");
const auth = jwt({secret: jwt_secret});
Then put the auth middleware before a route that you want to protect.
router.get("/secret/:uid", auth, profileCtrl.secret);

How can I inspect the set of Express.js middleware that is being used?

Backstory: I'm trying to debug an issue in one piece of middleware that I think is coming from other piece. But, I'm not sure. So anyway, I would like to be able to check what middleware is actually being called, because I'm not sure of the ordering.
Is it possible to inspect the set of middleware that is currently being used?
I have tried to find any piece of internal state where Express might be storing the middleware, but I was not able to.
You can't see what is specifically "middleware", but you can inspect all registered handlers.
In express 4:
// Routes registered on app object
app._router.stack
// Routes registered on a router object
router.stack
Fine for inspection/debugging, probably not a great idea to program against any variable prefaced with an underscore.
How middleware works:
The middlewares are generally used to transform a request or response object, before it reaches to other middlewares.
If you are concerned with the order in which the middlewares are called, express calls the middleware, in the order in which they are defined.
Example,
app.use(compression());
app.use(passport.initialize());
app.use(bodyParser());
app.use(cookieParser());
the order is
compression,
passport,
bodyParser,
cookieParser
(plus I think your bodyParser and cookieParser middlewares should be before the other middlewares like passport).
That is the reason why the error handling middlewares are kept at last, so that if it reaches them, they give an error response.
So basically, request drips down the middlewares until one of them says that it does not want it to go any further(get, post methods are such middlewares, that stop the request).
Now, the debugging part:
You may not be able to inspect the middleware properly internally, but you can check whether middleware has worked properly by inserting your own custom middleware in between and then put a breakpoint on it.
Let's say you want is to debug what happened to your request after the bodyParser middlewares does it tasks, you can do is put your custom middleware in between and check the request and response whether they are modified properly or not.
how you do this is by following example.
Example,
app.use(bodyParser());
//custom middleware to inspect which middleware is not working properly
app.use(function(req,res,next){
console.log("check something!"); //do something here/put a breakpoint
next();
/*this function is the third parameter
and need to be called by the middleware
to proceed the request to the next middleware,
if your don't write this line, your reqest will just stop here.
app.get/app.post like methods does not call next*/
});
app.use(cookieParser());
This is one way in which you move this custom debugger in between the middlewares, until you figure out which one is giving faulty outputs.
Also, if you want to check the middlewares functionality, you can look at the documentation of those middlewares. They are quite good.
Check by playing with your custom middleware.

Use Settings of Used Middleware

By "setting" I mean "something that is set", similar to "setters" in Java & other OO languages, not Express's "application settings". Is there a way to access and ideally use "settings" set inside middleware use()d by the app? In particular, some middleware is a full Express app, like vhost and the new Router middleware that comes with Express 4.x. If you do most of your routing in a virtual host and want to access some route param from the main app, that could be a problem. This is especially true if you have several layers, like I'm having, and it would be inconvenient to export the setting all the way out to the main app.
So is there a way to access these settings from the main app?
In particular, some middleware is a full Express app
Express 4.x has a great new feature to get around this problem. You can now use express.Router directly. In cases where you used to use an entire routing path by using a second sub-Express object as middleware, now you can just use Router.
For anything else, I usually add properties to the request object, namespaced by the name of my app.
function (req, res, next) {
req.myApp = req.myApp || {};
req.myApp.someData='whatever';
next();
}
The next middleware in the line will have access to this variable. I use this to track unique connection IDs, assigned by the first piece of middleware and subsequently used by others.

Resources