Three different Dashboard users

Have you read the ReadMe for the dashboard?

1 Like

You could have 3 instances of Node-Red running on different ports and have 3 Dashboards, 1 for each user.

It may be a "problem" for you, but it is working as designed. All connected users/clients have access to a single runtime instance of node-red -- so there is no multi-tenant solution readily available.

As mentioned, you would have to have 3 instances of node-red installed, with different subsets of your master flow running for each other user. Another option is to not use the dashboard, but that means you'd have to build your own web pages using something like node-red-contrib-uibuilder.

One other technique I've used is to have the navigation between the pages determined by sending msgs to a central ui_control node. That way, you can redirect someone away from pages they should not see, until they have entered some "password" or "keycode" that allows them to get to that page. If that would work for you, there is more information posted in this discussion thread. There is also another post that shows a simple keypad implementation that might be useful for you.

2 Likes

Thanks Shirckus, i will try it!

What about using cookies to manage the different users?

Since there is only one runtime server that is both single-threaded and single-tenant, I don't see how cookies will help...

This is not a traditional web application, with pages rendered dynamically for each end user -- it's a single page app that all users can see and interact with, while sending events back to the node-red server. Any new data that is sent to the dashboard widget nodes, on the back-end server, is passed to all the connected users to update their view of the dashboard in the front-end browser.

Another solution would be to do it entirely in 1 big ui_template. It is not currently secure as passwords would be visible on the source client-side but multiple users can all log-on with their passwords and only see what is intended for them :

<div ng-init="msg.password = ''">
<div>
    <label for="pass">Password</label>
    <input type="text" ng-model="msg.password" id="pass" required>
</div>
</div>
<div ng-if="msg.password == 'hello'">
    Page1 - Qty of silly hats
  <input type="number" ng-model="msg.payload.data1" name="quantity" min="0" max="1000">
  <md-button ng-click="send(msg)">Send</md-button>
  <md-button ng-click="msg.password = ''">Logout</md-button>
</div>
<div ng-if="msg.password == '123'">
        Page2 - Sister stuff 
  <input type="number" ng-model="msg.payload.data2" name="quantity" min="0" max="1000">
  <md-button ng-click="send(msg)">Send</md-button>
  <md-button ng-click="msg.password = ''">Logout</md-button>
</div>
<div ng-if="msg.password == '456'">
        Page3 - Parents page
  <input type="number" ng-model="msg.payload.data3" name="quantity" min="0" max="1000">
  <md-button ng-click="send(msg)">Send</md-button>
  <md-button ng-click="msg.password = ''">Logout</md-button>
</div>

Hey Steve (@shrickus),

But for another pull request you are hiding tabs based on a checkbox. So in that case data is also pushed (via dashboard widget nodes) to tabsheets that are not visible in the dashboard. Or does it not work that way?

So I'm wondering if you cannot do something similar: hide tabs based on a username instead of a checkbox? I have bet with my wife for 10 eur (which is my total monthly pocket money that I get from her) that you are able to implement such a pull request... So please don't let me down :pleading_face:
Bart

1 Like

What username? The dashboard doesn't know anything about users.

I was in fact referring to the username that I need to enter in the popup at login, but of course when the dashboard is not secured you don't have a username...

The dashboard can only be secured using httpNodeAuth which only supports one hardcoded username/password. You cannot have multiple users.

Damn, that is so true what you say. This really hurts ...

looks like your wife is going shopping !!! :wink:

... and i'm off the hook!

well, except i've still not been able to finish the PR :*(

Here's an update to the solution that I had proposed without showing the passwords in the source, it's still not secure as the passwords are sent to the client in msg.payload and could be viewed with an angular scope watching plugin. But since it's for your family, I'm guessing this is acceptable.

[
    {
        "id": "2dbd64d.dab389c",
        "type": "ui_template",
        "z": "dc84661.55bfb98",
        "group": "5625d033.1d56f",
        "name": "",
        "order": 0,
        "width": "6",
        "height": "5",
        "format": "<div ng-init=\"msg.password = ''\">\n<div>\n    <label for=\"pass\">Password</label>\n    <input type=\"text\" ng-model=\"msg.password\" id=\"pass\" required>\n</div>\n</div>\n<div ng-if=\"msg.password == msg.payload.pw1\">\n    Page1 - Qty of silly hats\n  <input type=\"number\" ng-model=\"msg.payload.data1\" name=\"quantity\" min=\"0\" max=\"1000\">\n  <md-button ng-click=\"send(msg)\">Send</md-button>\n  <md-button ng-click=\"msg.password = ''\">Logout</md-button>\n</div>\n<div ng-if=\"msg.password == msg.payload.pw2\">\n        Page2 - Sister stuff \n  <input type=\"number\" ng-model=\"msg.payload.data2\" name=\"quantity\" min=\"0\" max=\"1000\">\n  <md-button ng-click=\"send(msg)\">Send</md-button>\n  <md-button ng-click=\"msg.password = ''\">Logout</md-button>\n</div>\n<div ng-if=\"msg.password == msg.payload.pw3\">\n        Page3 - Parents page\n  <input type=\"number\" ng-model=\"msg.payload.data3\" name=\"quantity\" min=\"0\" max=\"1000\">\n  <md-button ng-click=\"send(msg)\">Send</md-button>\n  <md-button ng-click=\"msg.password = ''\">Logout</md-button>\n</div>",
        "storeOutMessages": false,
        "fwdInMessages": true,
        "templateScope": "local",
        "x": 700,
        "y": 660,
        "wires": [
            []
        ]
    },
    {
        "id": "cada3873.7413c8",
        "type": "inject",
        "z": "dc84661.55bfb98",
        "name": "",
        "topic": "",
        "payload": "{\"pw1\":\"hello\",\"pw2\":\"123\",\"pw3\":\"456\"}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "x": 530,
        "y": 660,
        "wires": [
            [
                "2dbd64d.dab389c"
            ]
        ]
    },
    {
        "id": "5625d033.1d56f",
        "type": "ui_group",
        "z": "",
        "name": "test",
        "tab": "9a95bc09.40d37",
        "disp": true,
        "width": "6",
        "collapse": false
    },
    {
        "id": "9a95bc09.40d37",
        "type": "ui_tab",
        "z": "",
        "name": "test25",
        "icon": "dashboard"
    }
]

@hugobox
how does it work with the three instances? what do I have to do to get this?

My trick is to have all the pages inside the ui-template and only show at first a password field. If the password matches one, then show the page. Have you tried importing my flow above? The passwords are 123, 456 and hello

Just make sure that the ui_template option: Add output messages to stored state is not selected as that would sync the dashboards which would defeat the trick.

Hi,
I would really like to know why authentication with the Node-RED Dashboard is not possible. Can anyone explain that to me ?

Thanks

Georg

To quote a very recent post to the slack channel by @dceejay

The dashboard is a plugin set of nodes for Node-RED so uses the same authentication as that. By default just a simple basic auth, but other schemes are possible to add via middleware.

Link to that here - https://node-red.slack.com/archives/C1DH77X1V/p1545118091102600
as there are a couple of follow ups.

  • You can enable basic authentication as described in the docs (https://nodered.org/docs/security#http-node-security) or read the ExpressJS docs about middlewere

  • to answer your question “why can not change the Node-RED authentication to allow such authentication in the Dashboard?” - the simple answer is because no-one has done it
    We know we need better auth options around the dashboard in particular - the existing options are not very flexible (basic auth only) or hard to do (custom middleware in your own express app).
    But no-one has sat down and designed what it would be and how it would work