Login for Dashboard UI *without httpNodeAuth*

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!

3 Likes

That is not strictly true. Nobody has provided a Dashboard feature that does it. That doesn't mean it isn't done. Probably the easiest way is to use a reverse proxy and put authentication decisions in the hands of the proxy. All proxies should handle this with ease and are likely to have good integration with other authentication mechanisms like OAuth, SAML, and services like Okta, AAD, LDAP, etc. since they are widely used in many different contexts.

I did a lot of searching for "how to authenticate the dashboard UI" and for any answer that didn't involve setting httpNodeAuth involved someone saying "...reverse proxy..." and the questioner pulling their hair out and running away. A lot of people put Node-RED on a RaspberryPi and just want to access the Dashboard UI remotely and don't want to make it more complex. This way, there's finally an example of how to provide basic authentication for the dashboard UI if all you want to do is run Node-RED without managing a reverse proxy. Node-RED offers SSL and Authentication configuration for the Admin, Node, and Static parts, so it only makes sense to show a way to extend that down to the Dashboard, which now that they allow setting the middleware, is possible -- and really needed to be shown in my opinion!

I do agree with you that the best answer is to put Node-RED behind a reverse proxy and manage all the endpoint authentication there. I already use haproxy to manage the SSL termination, so you've inspired me to work on further using haproxy as a complete API gateway!

Certainly not complaining that you have provided a useful example. I think that there are two reasons people haven't provided other examples:

  1. Most of us aren't doing auth because we don't need to, we don't expose Node-RED to the Internet directly. That covers much of the requirements for the home automation crowd.
  2. Those who do need to expose to the Internet often need something more robust and safe than basic auth. That is likely more orientated to professional use and those folk are likely to already have external infrastructure to provide external security.

Not saying these are the only use-cases of course but I suspect that they are common ones.

Those of us who work in security circles may not advise people to go for simple security solutions necessarily because we know how weak they can be and how easy it is to end up with something that looks secure but really isn't (a common failing of PKI based solutions including TLS). So we are likely to advise the use of a Telegram bot to avoid the issue altogether or, for the simple cases, the use of a secure configuration of a 3rd-party SSL VPN like NGROK where the secure configuration is relatively simple to achieve and harder to mess up.

In truth, setting up a reverse proxy is very easy and is easily done on a single Pi. It gives you a lot of flexibility, is scalable, can be easily secured (choosing something like Caddy with its integrated Let's Encrypt for example) and once set up, is very stable. But yes, it is daunting to a beginner.

Not going to argue there. All contributions are welcome anyway and I'm sure this will be sufficient for many people.

Cool, one of the reasons I often try to push people this way is to help them expand their horizons. It is amazing what you can do with a decent reverse proxy. But people using tools like Node-RED often get caught up in the amazingness of the tool and loose sight of the bigger picture - the other opportunities out there with just a little more tooling. Node.js is designed as a microservice architecture, it marries perfectly with reverse proxy front-ends which can provide security, flexibility, stability and scalability.

I sometimes see people tie themselves in knots trying to coerce Node-RED to do something that another tool has had thousands of man-hours invested to do just that thing already.

But of course, the amazing thing about Node-RED is that it fulfils so many use-cases and does so reliably. Just lets not loose site of other opportunities as well. :grin:

Thanks for your contribution to the community. You might also consider making an example flow of this and adding it to the Flows site?

Hi @philipsd6

thanks for sharing this. We've always known the (built-in) dashboard authentication options are somewhat limited, so the middleware option for added as a general catch-all solution. What we've lacked is a really good example of putting it to use - something you've provided here.

We should figure out where we can add this to the dashboard docs to make it easier for users to discover in the future.

3 Likes

I'm not sure how this could be done as a flow... it's just setup and configuration, um... I guess a tiny bit of javascript programming too.

It would be nice if the Admin authentication could be reused as the dashboard middleware... I tried to mount the dashboard as /admin/ui to see if I could somehow magically leverage the admin authentication, but of course that was silly since no matter where it's mounted, the admin is a completely separate express app. Conceptually the dashboard is nearly as much "admin" as the editor. I wanted to see if I could check the request to see if it was authenticated, and redirect to the admin login, but... again, as they are separate apps, I couldn't see how to accomplish that from the dashboard middleware, so I still feel like my method here is a bit "hacky".