I think that a typical setup of Node-RED uses the Dashboard UI, as well as some webhooks for various services. I find it very surprising that no-one has ever (as far as I could find) provided a reasonable solution for requiring authentication for the UI, while leaving the webhooks open (since those are usually protected by secrets.)
I am by no means a skilled javascript/express.js developer, but I'm pretty happy with my solution based on express-basic-auth
and rate-limiter-flexible
and the example code from those projects... (Make sure to install both in your Node-RED installation directory!)
settings.js:
// Add basic auth middleware for the Dashboard UI.
const basicAuth = require('express-basic-auth');
function getUnauthorizedResponse(req) {
return req.auth
? ('Credentials ' + req.auth.user + ':' + req.auth.password + ' rejected')
: 'No credentials provided'
}
// Add rate limiting middleware to inhibit brute forcing
const { RateLimiterMemory } = require('rate-limiter-flexible');
const rateLimiter = new RateLimiterMemory({
points: 5, // 5 requests
duration: 30, // per 30 seconds
});
const rateLimiterMiddleware = (req, res, next) => {
rateLimiter.consume(req.ip)
.then(() => {
next();
})
.catch(() => {
res.status(429).send('Too Many Requests');
});
};
module.exports = {
// ...snip...
ui: {
path: "/ui",
middleware: [
rateLimiterMiddleware,
basicAuth({
users: {'ui_username': 'ui_password'},
challenge: true,
realm: 'Dashboard UI',
unauthorizedResponse: getUnauthorizedResponse
})
]
},
// snip...
}
I hope this is useful to others!