express.js - use middleware for non static urls only - node.js

How do i create middleware that runs on all urls that arent serving static files?
i was thinking of checking if req.url doesnt start with "/js/", "/css/" or "/images/" but there must be a better way

The easiest (and fastest) way is to put your static file middleware ahead of your 'catch all' middleware:
app.use(express.static(STATIC_DIR_HERE));
app.use(function notStatic(req, res, next) {
// everything here will be non-static routes
});
(where app is your express instance)

Related

NodeJs/Express: Authorise all endpoints except one

In my NodeJs/express based application, I am authorizing calls to all the endpoints by using the following middleware.
app.use(restrictByCookieMiddleware);
I want to authorize all endpoints except one i.e. I don't want "restrictByCookieMiddleware" middleware to run for "/metrics" endpoint. Is there a way to escape one endpoint?
Here, I found some examples that matches endpoint for which middleware should run, I am looking for a solution that skips one.
Your have a couple of choices:
First, you can just define the one exception route handler BEFORE the middleware. Then, it will handle that route and the routing will never get to the middleware.
app.get("/login", (req, res) => {
// handle that one special route here
});
// all other routes will get this middleware
app.use(restrictByCookieMiddleware);
Second, you can make a wrapper for the middleware that compares to the one specific route and skips the middleware if it's that route:
app.use((req, res, next) => {
// shortcircuit the /login path so it doesn't call the middleware
if (req.path === "/login") {
next();
} else {
restrictByCookieMiddleware(req, res, next);
}
});
// then, somewhere else in your code would be the /login route
app.get("/login", ...);
Third, if you have multiple routes that you want to skip the middleware for, you can segment things by router. Create a router for the non-middleware routes and put all of them on that router. Hook that router into the app object first.
Then, create a second router that contains the middleware and has all your other routes on it.
Place that specific route, you want to exclude, before this line:
app.use(restrictByCookieMiddleware);
So this will solve your problem.

Stop duplication of passportjs isAuthenticated code in Express route files

I am using passportjs for my authentication.
I have lots of different routes throughout the project, 95% of them require the following function:
// Middleware functions
function isAuthenticated(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/login');
}
At the moment, I am putting this function at the bottom of EVERY route file.
Is there a way to write it once, and be able to use it in all the route files?
If you add that middleware before the routes that require it, all requests will pass through it before they get forwarded to the correct route handler:
// doesn't require an authenticated request
app.use(router1);
// add the middleware just once
app.use(isAuthenticated);
// all following route(r)s require an authenticated request
app.use(router2);
app.use(router3);
...

Match API and isomorphic routes

I have an isomorphic app running on express:
app.get('*', (req, res) => {
match(
{ routes, location: req.url },
(error, redirectLocation, renderProps) => { ... }
Currently I'm matching on the wildcard as this is the approach I've seen taken in most boilerplates and tutorials I've seen.
This issue is now that I need to be able to match specific routes such as /auth and /api which need to be handled differently to the routes for the isomorphic app. i.e. the /auth route needs to authenticate a user.
I need a way to be able to specify those routes but then still maintain the wildcard matching for the routes used my the isomorphic app.
I've considered that instead of using a wildcard matcher I could collect all of the routes for the isomorphic app in to an array and provide that to express instead:
const isoRoutes = ['/home', '/about'];
app.get([isoRoutes], (req, res))
I'm not sure if there's a better way to achieve this though?
If your /auth and /api routes aren't serving pages from your app (i.e. you're using them for AJAX calls), you should have separate request handlers for them.
As long as you specify the non-wildcard routes ahead of the wildcard get, you should be fine with the wildcard.
app.get('/auth', handleAuth);
app.get('/api', handleAPI);
app.get('*', handleRender);
You can code like this:-
req.url.match(//regular expression);
Match() only works with a regular expression.

Express.js - How to set a header to all responses

I am using Express for web services and I need the responses to be encoded in utf-8.
I know I can do the following to each response:
response.setHeader('charset', 'utf-8');
Is there a clean way to set a header or a charset for all responses sent by the express application?
Just use a middleware statement that executes for all routes:
// a middleware with no mount path; gets executed for every request to the app
app.use(function(req, res, next) {
res.setHeader('charset', 'utf-8')
next();
});
And, make sure this is registered before any routes that you want it to apply to:
app.use(...);
app.get('/index.html', ...);
Express middleware documentation here.

Using middleware with express().use along with express.static

I'm using PassportJS to secure a WebApp (written with AngularJS). I'm using NodeJS with Express (4.0.0) to serve static content after the login-screen. I don't get how to use a middleware along with express.static() at the same time.
My (not working) code looks like
app.use('/secure',
function (req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
},
express.static(__dirname + '/../../client'));
The plan is, that the middleware ensures, that the user is only forwareded to the WebApp if he/she is logged in. If not, he/she/it is redirected to the root folder.
I found this answer, but according to the documentation, the new version supports multiple functions. This isn't the "clean" solution I'm looking for, since the directory contains too many subfolders and files.
Thanks in advance
When you attach middlewares to the same route they get executed in the same order of declaration, so if you want to execute any middleware before express.static, all what you have to do is attach it to the same route and declare it before.
app.use('/secure', myMiddleWare);
app.use('/secure', express.static(__dirname + '/../../client'));

Resources