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?
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'));
You can do something like this as well https://gist.github.com/gevorg/7168d5f02c1ca5362b2a#file-specific-path-js
// Express module.
var express = require('express');
// Authentication module.
var auth = require('http-auth');
var basic = auth.basic({
realm: "Simon Area.",
file: __dirname + "/../data/users.htpasswd" // gevorg:gpass, Sarah:testpass ...
});
// Application setup.
var app = express();
app.use(function(req, res, next) {
if ('/specific/path' === req.path) {
next();
} else {
(auth.connect(basic))(req, res, next);
}
});
// Setup route.
app.get('/', function(req, res){
res.send("Hello from express - " + req.user + "!");
});
// Setup guest route.
app.get('/specific/path', function(req, res){
res.send("Hello from express - guest!");
});
// Start server.
app.listen(1337);
The accepted answer to this question is not desirable, as the route order can be important!
A better way to do it would be to pass basic-auth as second argument for your route definition:
app.get('/admin', auth.connect(basic), (req, res) => {
res.send(`Hello from admin area - ${req.user}!`);
});
Or
app.use('/admin', auth.connect(basic), myCustomRoute);