UI Builder - Client Identification (HTTPHEADERS)

I've been using UI-Builder to create an interface that allow users to enter data which is sent be to another backend server using MQTT. Everything is properly working, but I am facing an issue which I can't seem to resolve: knowing which user sent out the data. I am NOT looking for something like security where a user would login with username and password. If I could only get something, like the local IP of whom initiated the request, I would then do the match in the backend server.

Is there something that could be done? Is something like the HTTPHEADERS sent from the client browser available somewhere or somehow? Or how can I use the "control msg" for that?

Thanks

Hmm, I first thought you would be able to get this by making use of the middleware feature built into uibuilder.

You can create an external file containing an exported function that matches the signature of an ExpressJS middleware function. That file goes into ~/.node-red/uibuilder/.config/uibMiddleware.js and you should find such a file already in place with some notes and a commented out function.

But on further thinking, that won't let you get the data back into Node-RED. That is perhaps a failure on my part and maybe needs to be a subject of an enhancement?

My second thought was to abuse the new security functions. These are not finalised though and would likely have other unwanted side-effects right now.

There are two remaining ideas - and sorry for the thinking out loud as I worked through all this.

  1. In your front-end code, simply add the client IP address when sending data back to Node-RED. This is nice and easy to do. Wouldn't pass muster for security but may be good enough for what you want.

  2. Use the control messages to track when a new client connects or when their socketid updates. This is not necessarily ideal though since a client may change its socketid if it loses connection then reconnects or if the user reloads the page.

So probably option 1 is your best bet - at least for now.


But let me throw this back to yourself. What do you think would be the ideal solution?

Here are some longer term enhancements that I might include, let me know if you think one of them stands out as a better solution to option 1 above.

  1. Add an advanced option that, if selected, exposes more of the ExpressJS/Socket.io data on the output msgs.
  2. Add another standard function to the ~/.node-red/uibuilder/.config/security.js code that bridges the Express.js and Socket.IO data with the auth data allowing you to return what you wanted to into the output msg.

Thanks for taking the time to answer and I don't mind that your thinking it out loud as your replying... it's better to get options that a simple "No, can't do it!".

Thinking this thoroughly, I believe that the I am going down a wrong path and should not rely on the IP (especially since I need the local IP since NR is being ran in an Intranet). I did try to get the client to send the IP. Using this answer from StackOverflow, it did provide an IP (altered by Chrome/Firefox since the real IP could pose a security issue).

I think the best thing would be to wait for the security feature that you are currently implementing.

In the meantime, I just may have found an alternative and was wondering if it would work. What if I gave each of my user specific hyperlink? The would all get the same base URL to the uibuilder node (127.0.0.1:1880/dispatcher-adm) but the I would a GUID for each user (something that would be known to my other server). This would look like that:
User A: ...127.0.0.1:1880/dispatcher-adm/aaaa1234 OR .../dispatcher-adm?user=aaaa1234
User B: ...127.0.0.1:1880/dispatcher-adm/bbbb5678

Could that work? How can I get the parameter in uibuilder? Do I need to use VueRouter?


About the question you ask me. If I understand it correctly, option 2 would provide more flexibility since each developer might need different thing sent out depending on the security strategy they use.

But I don't know. I only began to use VueJS since using UIBuilder so there is still a whole lot that I need to understand... Escpecially ExpressJS ans SocketIO stuff.

I don't think it would. Because you have the same issue. The URL is only tied back indirectly to the uibuilder instance. There is currently no way to consume the extra URL info as an output from uibuilder.

Though certainly I could add an option to allow that to happen - that could be part of my longer term advanced option 1 above. If you selected a flag in uibuilder, it would return some Express and/or Socket.io information to the output messages. But that isn't there at the moment.

Ah, good thinking, that should help as you can then extract the extra URL parameters in the front-end and include them in any messages you send back to Node-RED. So actually, that would be OK.

But then there are other ways to achieve the same ends without URL parameters too. For example, give the users an ID (but no password unless you want to) and have a UI element that lets them enter it. Save that in the browser in local storage so that it is retained - 1 line of code to save, another to retrieve on startup/reload. A simple wrapper function to include the data when you want to send a msg to Node-RED.

Either should work.

Hmm, not sure there is actually that much difference in terms of flexibility. option 1 gives immediate access to the extra data on the output messages and so is the more "node-red way". Option 2 requires you to write some JavaScript code in the right format but indeed could end up giving you more options at the cost of more complexity.

Might end up with both. Probably not a lot of effort to make them happen.

I will add both options to the backlog and see where that goes.

1 Like