Multi-user dashboard idea and proof of concept

1,956 views
Skip to first unread message

Mike Blackstock

unread,
Mar 19, 2017, 12:02:07 AM3/19/17
to Node-RED
Hi all,

As we all know, currently the dashboard nodes provide a global UI for all users/browsers who access it.  I've seen request on this group, and feedback from FRED users where they would like dashboards that present different information for individual users or groups of users.

For example, if data for a sensor coming in from MQTT is ‘owned’ by a certain user or group of users, it should be possible to target dashboards with data that only that user or members of the group are viewing. Similarly, it should be possible to receive input messages from dashboards that indicate which user and/or group they are coming from.  It would also be useful to change how the dashboard looks depending on the user that has logged in.

To support all this, we’d need a log in system and a way to protect the dashboard URL from users that haven’t logged in.

Toward addressing this feedback, I’ve started to implement a proof of concept by modifying the dashboard node package.

Proof of concept so far: 

Supports a ‘dashboard token’ containing information about the user: specifically, the username and a list of ‘roles’ which are strings. The idea is that a user management system can generate a signed verifiable token (JWT) in a cookie that contains this information for use by the dashboard.

Configuration settings for the dashboard to redirect to a login page if there is no dashboard token presented on connection, set the JWT secret, etc.

If there is a dashboard token, and the dashboard is configured to use it, the system associates every dashboard connection to node red with the username and list of roles contained in the token.

To target a message to a specific user, or role, you include a message property when sending data to the dashboard: 'user' - send message only to this user’s dashboards, 'role' - send message to all user’s dashboards who have this role.

When a message is received by a dashboard, we include the user and roles in the message so that node logic can make requests or process data on a per-user or role basis.

Finally, I’ve added a ‘role’ configuration to the tab nodes. If this is set, tabs will be filtered by role: tabs with an ‘admin’ role will be shown only to users who have this role for example. If no role is specified, all users will be able to view the tab.

Roughly how it works:

We assume a cookie containing a verifiable user name and list of roles is used on connection - using JWT for example. If this cookie is not present we, send a redirect message to the dashboard containing a configurable URL for user log in. (In the PoC I use a simple Node-RED flow for the login URL, and the cookie is not secured yet - work in progress).

Socket.io supports server-side groups called ‘rooms’. When a user connects, we check the cookie and add the socket to a user room, and one or more role rooms. This way we can target users and groups with messages based on message properties.

We associate a client socket with the user and their roles. When messages come in from the UI, we add these to the message before it goes into the flow logic.

When UI updates are sent to the dashboard, we check to see whether the tab roles are in the list of user roles for each socket. If not, the tabs are filtered out so that only users in a given tab role can see the tab. Tabs without a role are displayed to everyone.

For standalone node-red - it might be good to somehow connect this as an option to the built in NR user authentication system. Need to think about how this might be done.

I hope this explains things, OK, but questions and feedback is welcome.  The code is work in progress at https://github.com/mblackstock/node-red-dashboard/tree/multi-user-dashboard

Mike

Mike Blackstock

unread,
Mar 22, 2017, 1:45:56 PM3/22/17
to Node-RED
In case there is anyone following this thread, the biggest open issue from what I can see so far is that the current dashboard maintains global state for each widget (node) to redraw the widget with the last value when new browsers connect, and maintain chart history in RAM.

To support multiple dashboard users or roles, we'd need to rework this area of the dashboard framework to store state for each user / role and possibly provide a storage plugin facility for maintaining this state between restarts.

I'm going to shelve this for now, but if anyone who is deep into the dashboard code is interested in pushing this idea forward, let me know.  Maybe it could be put on the dashboard project to do list under 'new' or 'epic ideas' :-) My code and findings are at https://github.com/mblackstock/node-red-dashboard/tree/multi-user-dashboard and https://github.com/mblackstock/node-red-dashboard/wiki/Multi-user-dashboards

Cheers,
Mike

I've decided to shelve this for now, but if you have any comments or questions on this, feel free to drop me a note.  

PM

unread,
Apr 11, 2017, 12:59:39 PM4/11/17
to Node-RED
On Wednesday, 22 March 2017 18:45:56 UTC+1, Mike Blackstock wrote:
In case there is anyone following this thread,

I do now.
Thank you so much!
Some (many) people need it, but it seems it never goes through :(

Jéan Roux

unread,
Apr 11, 2017, 2:38:38 PM4/11/17
to Node-RED
Mike, sorry to hear you are shelving it.... Somewhere on the horizon we need a solution for this......

mattb...@gmail.com

unread,
May 25, 2017, 4:58:35 PM5/25/17
to Node-RED

I agree, I am also very sorry to hear this is being parked.  Hope someone is able to pick it up.. 

In the mean time, do you know if there is a way to put simple buttons behind a password.  For example if I have a central NodeRed console in the house, and it can turn the fireplace on and off.  i dont want the kids turning it on and off.

Mike Blackstock

unread,
May 25, 2017, 6:06:22 PM5/25/17
to Node-RED
Hmm, maybe I can carve off that bit of code that did the user login for dashboards... I actually used an HTTP flow for the authentication bit if I remember.  I'll try to have a look.

mike

Julian Knight

unread,
May 26, 2017, 4:00:50 AM5/26/17
to Node-RED
If you don't mind the overheads of putting your own page together, I made sure that node-red-contrib-uibuilder included the same auth features that the http nodes respond to though honestly, not really tested it. Certainly the optional Express middleware works.

steve rickus

unread,
May 26, 2017, 9:06:51 AM5/26/17
to Node-RED
I can think of a couple "low tech" ways to do that with basic node-red, if your security needs are not that high...

One of my flows needs to have a certain global value set, so i don't want to render the dashboard page unless it exists. I built a simple "connect" tab with a ui_form to collect the info I need (along with a secret key). The output goes to a function (or switch) node that ensures the key is expected, and if so copies the info to global context. Then it uses a change node to pass the name of the "protected" tab to a ui_control node, which causes dashboard to switch to that dashboard tab (page). Upon leaving that page, clear the global value and the process resets.

Then, to keep anyone from switching directly to that protected page from the menu, I check any output msg from ui_control (which sends a tab "change" msg) -- if it detects the global value is not set, it immediately sends the name of the "connect" tab back to ui_control, which sends them back to the beginning.

As I said, not so much "security" as a "hurdle", but it may be enough in this case.
--
Steve

mattb...@gmail.com

unread,
Jul 4, 2017, 5:22:33 PM7/4/17
to Node-RED
Steve, I thought this would do the job.  I just went to implement and I realized that once the global value is set, its set for everyone.  i.e.  I am at home, set the value, turn the fire off, then forget to set the value back (or at the same time), someone else comes along to the public internet side, and notices they they control my pool heater because the global value is set, so turns that on.

I thought about a separate internet facing node-red dashboard, but then that limits my ability to do remote actions, while also showing some basic data.

Julian Knight

unread,
Jul 5, 2017, 12:43:25 PM7/5/17
to Node-RED
The easiest way to do secure remote commands is to implement a Telegram bot. You do have to configure each command you want but that is good for security anyway. Telegram lets you share your channel with whoever you want and you can also further restrict commands to a list of individual users. No messing with web pages, proxies, TLS and all the rest. Telegram takes care of all the security and all of the comms channels are encrypted end-to-end.

If you follow a dashboard route, you have to add TLS security both for the page AND for the websocket connections. The websocket security is hard.

Walter Kraembring

unread,
Jul 5, 2017, 2:47:44 PM7/5/17
to Node-RED
Julian, I certainly do agree about everything you say about Telegram regarding the security as well as the performance (I do use it myself but mainly for error and alarm events from my NR home automation). However, using Telegram as a ui is maybe ok with us technology guys but it would not work for the rest of my family or relatives, then it becomes too complicated

I was just thinking about an idea but it is maybe not possible, what about having some kind of nice looking gui that is using telegram as an underlying service? If Telegram has some suitable api...maybe

Kind regards, Walter 

Julian Knight

unread,
Jul 6, 2017, 12:07:01 PM7/6/17
to Node-RED
It is certainly a different approach and you need to cast off the old ways! ;)

You need to think along conversational lines instead of switches and forms. Actually, conversational interfaces are the current state of the art in UI's so having a toolset that makes it so easy is great. 

I have a channel that is nominally "the house". The house broadcasts warnings such as excessive humidity or the doorbell being pressed and you can simply ask the house about things or tell it to do things "turn on the livingroom light" for example. Or, more succinctly "hall light on". Questions might be "is the iron on".

The trick is often defining a number of conversational paths including ones where the user gives only a little info and the bot prompts for more:

User: light
Bot: which light would you like to switch?
User: hall
Bot: the hall light is off, turning it on now

You can augment these interactions with buttons if that makes sense to the conversation. Buttons work well if there are only a few responses possible.

Walter Kraembring

unread,
Jul 6, 2017, 1:10:31 PM7/6/17
to Node-RED
Yes, that sounds more like it. If it is possible to give the bot this kind of "AI", then I think it will be possible to use also for grandma. I haven't look deep enough on how to create such an intelligent bot though but it sounds really something I would like to try out. Was it difficult to create your example?

Julian Knight

unread,
Jul 6, 2017, 3:20:56 PM7/6/17
to Node-RED
Well there is certainly a learning curve but now that the redbot nodes have matured a bit, it is a lot easier.

In particular, check out the "rivescript" node which makes conversational interfaces a lot easier to create and manage.

The original telegram node is OK and can certainly be used to create these kinds of interface but it gets fairly complex quite quickly due to the involved logic of the user/bot interactions. Rivescript was designed specifically to handle this kind of thing.

Once you have your basic interaction working, it isn't difficult to expand the interaction.

Walter Kraembring

unread,
Jul 7, 2017, 10:35:40 AM7/7/17
to Node-RED
Thank You, that is an impressive set of nodes I must say!!!
Kind regards, Walter
Reply all
Reply to author
Forward
0 new messages