user2064000 user2064000 - 6 months ago 16
Node.js Question

Using HTTP basic auth for certain URLs only with Express framework

I have a node.js application designed using the Express framework and the http-auth module, as follows:

var auth = require('http-auth');
var express = require('express');
// ...
var mywebapp = express();
// ...
if (usebasicauth) {
var basic = auth.basic({realm:"MyRealm", file:"/srv/config/passwd"});
mywebapp.use(auth.connect(basic));
}

mywebapp.use('/js', express.static(__dirname + '/files/js'));
mywebapp.use('/css', express.static(__dirname + '/files/css'));
// ...


However, I don't want to protect assets available under the
/js
and
/css
directories. This is what I tried doing:

if (usebasicauth) {
var basic = auth.basic({realm:"MyRealm", file:"/srv/config/passwd"});
mywebapp.use(function(req, res, next) {
if (/^\/(css|js)/.test(req.url)) {
next();
}
else {
auth.connect(basic);
}
});
}


Trying to access URLs under
/css
and
/js
work as expected; however, other URLs never load.

How can I make other URLs work as expected?

Answer

The order of mywebapp.use is important. If you have first mywebapp.use(auth.connect(basic)); then it will be used for every request but if you change the order it will pass statics and be only used for whatever is after it.

The middleware functions are processed in order they are added.

So following should do what you want.

// no auth for statics
mywebapp.use('/js', express.static(__dirname + '/files/js'));
mywebapp.use('/css', express.static(__dirname + '/files/css'));
// auth reguired from here 
mywebapp.use(auth.connect(basic));

If you place mywebapp.use(auth.connect(basic)); above express.static it will reguire auth for it as well.

// auth reguired from here 
mywebapp.use(auth.connect(basic));
// auth required for statics as well
mywebapp.use('/js', express.static(__dirname + '/files/js'));
mywebapp.use('/css', express.static(__dirname + '/files/css'));