Login and Password in dashboard (localhost:1880/ui)?!


#1

Hi,
i wish to put a login and password in my interface dashboard (localhost:1880/ui) like in (localhost:1880) how i can do that please?!

Thank you for your help.


#2

#3

Thank you , but i think that this solution it's made for code dashboard(localhost:1880) and not for my interface dashboard (localhost:1880/ui)
Thank you for your help.


#4

you should move either the editor - see the httpAdminRoot entry in settings.js,
or the http path - httpRoot. The dashboard is off {httpRoot}/ui so securing that uses the method for httpRoot


#5

Thank you for your response, but i don't understand, I have to uncomment this lines?!!
node-red
thank you for your help.


#6

Hello Imadouino,

For the UI edit on settings.js to set an user & passw for HTTPS , I think this is what you wanted.

Uncomment and edit as follows:

// To password protect the node-defined HTTP endpoints (httpNodeRoot), or
// the static content (httpStatic), the following properties can be used.
// The pass field is a bcrypt hash of the password.
// See http://nodered.org/docs/security.html#generating-the-password-hash
httpNodeAuth: {user:"xxxx",pass:"xxxx"
httpStaticAuth: {user:"xxx",pass:"xxxxx`

Regards


#7

Thank you it's work !!! !


#8

Question about securing the ui dashboard with httpNodeAuth as indicated (but not explained well) here:
https://nodered.org/docs/security#http-node-security

Do I understand correctly that turning on httpNodeAuth will add a user/pw login screen not only for accessing the ui dashboard, but also for any POST APIs ("http in" nodes) my flows are relying on?
i.e. external apps need to be able to login to my Node-Red instance in order to send POST messages to my node-red application?

If this is correct, is there any way to protect the ui dashboard without hindering my incoming POST APIs?


#9

No - they currently both use the same express path. (from the Core of Node-RED point of view the dashboard is just another http endpoint)
It is something we want to get to at some point - but isn't short term.


#10

OK thanks for clarifying.

So if I use the ui dashboard as a control panel of any kind i'd need to add some sort of authentication at least. Let me know if you have any best-practices or common mistakes... I'm thinking of just adding a password that needs to be typed in or something like that as a minimal work-around.


#11

I've seen some examples where the dashboard shows a numeric pin pad -- once you enter the correct code, it redirects you to other dashboard "pages". It's definitely a low-tech way to provide some basic "security", but it sounds like it would work for your situation.

image

[{"id":"7d92dedf.5c1b3","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 1","order":1,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '1' })\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-1\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">1</text>\n </g>\n</svg>\n</md-button>\n","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":110,"y":380,"wires":[["49d71834.096548"]]},{"id":"39cd572c.1e4138","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 6","order":6,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '6'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-6\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">6</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":390,"y":420,"wires":[["49d71834.096548"]]},{"id":"d9986fc8.49167","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 3","order":3,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '3' })\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-3\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">3</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":390,"y":380,"wires":[["49d71834.096548"]]},{"id":"513389a4.589638","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 4","order":4,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '4'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-4\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">4</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":110,"y":420,"wires":[["49d71834.096548"]]},{"id":"2a464b8b.558314","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 5","order":5,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '5'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-5\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">5</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":250,"y":420,"wires":[["49d71834.096548"]]},{"id":"2de88430.b7864c","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 7","order":7,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '7'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-7\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">7</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":110,"y":460,"wires":[["49d71834.096548"]]},{"id":"1f5853d8.36dbdc","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 2","order":2,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '2' })\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-2\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">2</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":250,"y":380,"wires":[["49d71834.096548"]]},{"id":"76ea846e.bfbe4c","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 8","order":8,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '8'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-8\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">8</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":250,"y":460,"wires":[["49d71834.096548"]]},{"id":"b92fbf33.e21cc","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 9","order":9,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '9'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-9\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">9</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":390,"y":460,"wires":[["49d71834.096548"]]},{"id":"e167bcb5.de23","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key *","order":10,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '*'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-Reset\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\">\n    <title>Reset</title>\n  </rect>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"50\" y=\"250\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 250px; font-family: Arial;\">*</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":110,"y":500,"wires":[["49d71834.096548"]]},{"id":"54f95096.51461","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key 0","order":11,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '0'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-0\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\"/>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">0</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":250,"y":500,"wires":[["49d71834.096548"]]},{"id":"3569b378.05d7ac","type":"ui_template","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","name":"Key #","order":12,"width":"2","height":"2","format":"<md-button class=\"vibrate filled touched bigfont rounded\" style=\"background-color:#333333\" ng-click=\"send({payload: '#'})\"> \n<svg width=\"105px\" height=\"105px\" version=\"1.1\" viewBox=\"0 0 200 200\">\n <g id=\"Key-Enter\">\n  <rect fill=\"#4D4D4D\" width=\"200\" height=\"200\" rx=\"12\" ry=\"12\">\n    <title>Enter</title>\n  </rect>\n  <path fill=\"none\" stroke=\"#B3B3B3\" stroke-width=\"7.99957\" d=\"M6 194c-1,-1 -2,-3 -2,-6l0 -176c0,-4 4,-8 8,-8l176 0c2,0 4,1 6,2\"/>\n  <path fill=\"none\" stroke=\"#1A1A1A\" stroke-width=\"7.99957\" d=\"M194 6c1,1 2,3 2,6l0 176c0,4 -4,8 -8,8l-176 0c-2,0 -4,-1 -6,-2\"/>\n  <text x=\"59\" y=\"153\" style=\"fill: #E6E6E6; font-weight: normal; font-size: 150px; font-family: Arial;\">#</text>\n </g>\n</svg>\n</md-button>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":390,"y":500,"wires":[["49d71834.096548"]]},{"id":"f99d83cc.b54df","type":"ui_text","z":"c54ebe65.60eaa","group":"d4851ecc.b4b53","order":13,"width":0,"height":0,"name":"keys pressed","label":"Number:","format":"{{msg.payload}}","layout":"row-spread","x":610,"y":380,"wires":[]},{"id":"49d71834.096548","type":"function","z":"c54ebe65.60eaa","name":"code entry","func":"var key = msg.payload;\nvar out = context.get(\"code\") || \"\";\n\nif (key === \"#\") {\n    key = \"\"; // send code\n}\nelse if (key === \"*\") {\n    key = \"\"; // reset code\n    out = \"\";\n}\nelse if (!isNaN(+key)) {\n    out += key; // append key\n}\ncontext.set(\"code\", key ? out : undefined);\n\n// output #1: keys entered\n// output #2: completed code\nmsg.payload = out;\nreturn [\n    key ? msg : {payload: \"\"},\n    out ? msg : null\n];","outputs":2,"noerr":0,"x":570,"y":440,"wires":[["f99d83cc.b54df"],["abbb2a40.b43368"]],"outputLabels":["last key number","completed code"]},{"id":"abbb2a40.b43368","type":"debug","z":"c54ebe65.60eaa","name":"code entered","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","x":610,"y":500,"wires":[]},{"id":"d4851ecc.b4b53","type":"ui_group","z":"","name":"Keypad","tab":"f71dee08.232e9","order":5,"disp":true,"width":"6"},{"id":"f71dee08.232e9","type":"ui_tab","z":"","name":"Button Panel","icon":"dashboard"}]

In one of my posts, I mentioned using a global variable to hold some "code entered ok" flag, and checking that is set whenever a new dashboard page is opened. The ui_control node can be used to send any unauthorized user back to the pin pad.


#12

Steve,
the keypad doesn't look so good in macOS in any of the browsers:


#13

maybe need to adjust borders, gap of the overall dashboard, etc...