Need Help to Create Login and Sign Up Page with Session

Hi all,

I really need an help here to create a login and sign up page in Node-Red with session and page redirect (to indicate successful and failure with username). I'm able to create the pages and functions, but stuck at session and page redirect part. Username and password will be managed in MySQL database. The following consists of two types of flow for login. I'm not sure which one is the correct method to implement here.

Flow 1

[{"id":"f7511300.c34c4","type":"mui_form","z":"6ddaac4.fd62654","name":"login-form","label":"<center><font color=\"#004080\">Welcome to <b>I4</b>Inari</font></center>","group":"b4e7b289.a5dd4","order":0,"width":0,"height":0,"options":[{"label":"Username","value":"username","type":"text","required":true},{"label":"Password","value":"password","type":"password","required":true}],"formValue":{"username":"","password":""},"payload":"","topic":"","x":100,"y":120,"wires":[["69c991a1.ab4da"]]},{"id":"69c991a1.ab4da","type":"function","z":"6ddaac4.fd62654","name":"select-query","func":"//Read username and password\nvar username = {payload: (msg.payload.username)};\nvar password = {payload: (msg.payload.password)};\n\n//SELECT Query\nmsg.topic=\"SELECT COUNT(*) AS count FROM users WHERE name='\" + username.payload + \"' AND user_name='\" + password.payload + \"'\";\n\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":120,"wires":[["2417a41b.7a67bc"]]},{"id":"2417a41b.7a67bc","type":"mysql","z":"6ddaac4.fd62654","mydb":"272ea16.4569d5e","name":"database","x":440,"y":120,"wires":[["f1d2d3f5.96db4"]]},{"id":"f1d2d3f5.96db4","type":"function","z":"6ddaac4.fd62654","name":"check","func":"var count = msg.payload[0].count;\n\nif (count > 0)\n{\n    msg.payload = \"Login successful\";\n}\nelse\n{\n    msg.payload = \"Login failed\";\n}\nreturn msg;","outputs":1,"noerr":0,"x":590,"y":120,"wires":[["9a1cb371.7387c"]]},{"id":"9a1cb371.7387c","type":"mui_text","z":"6ddaac4.fd62654","group":"b4e7b289.a5dd4","order":0,"width":0,"height":0,"name":"login-result","label":"","format":"{{msg.payload}}","layout":"col-center","x":750,"y":120,"wires":[]},{"id":"b4e7b289.a5dd4","type":"mui_group","z":"","name":"Welcome to I4Inari","tab":"c6b47aa.71d9788","order":2,"disp":false,"width":"6","collapse":false},{"id":"272ea16.4569d5e","type":"MySQLdatabase","z":"","host":"","port":"3306","db":"ram_test","tz":""},{"id":"c6b47aa.71d9788","type":"mui_tab","z":"","name":"I4Inari","icon":"home","order":1}]

At this flow, I'm aware that we are able to use ui control to redirect to another tab. However, I'm stuck at the syntax {tab:"tab_name"}. I'm unable to redirect the tab. I did add a function node and pass this syntax via msg.payload, but it didn't work.

Flow 2

[{"id":"38350c2b.4548d4","type":"http in","z":"6ddaac4.fd62654","name":"","url":"/login","method":"get","upload":false,"swaggerDoc":"","x":100,"y":240,"wires":[["1d5300c7.b0ac5f"]]},{"id":"1d5300c7.b0ac5f","type":"template","z":"6ddaac4.fd62654","name":"login-page","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"\">\n    <link rel=\"icon\" href=\"\">\n\n    <title>I4Inari</title>\n\n    <!-- Bootstrap core CSS -->\n    <link href=\"\" rel=\"stylesheet\">\n\n    <!-- Custom styles for this template -->\n    <link href=\"\" rel=\"stylesheet\">\n  <script type=\"text/javascript\"></script><link rel=\"stylesheet\" type=\"text/css\" href=\"\" /></head>\n\n  <body class=\"text-center\"><script type=\"text/javascript\" language=\"javascript\" src=\"\"></script>\n    <form class=\"form-signin\" method=\"post\">\n      <img class=\"mb-4\" src=\"\" alt=\"\" width=\"125\" height=\"125\">\n      <h1 class=\"h3 mb-3 font-weight-normal\">Welcome to <b>I4</b>Inari</h1>\n      <label for=\"inputEmail\" class=\"sr-only\">Username</label>\n      <input type=\"text\" id=\"inputEmail\" class=\"form-control\" name=\"username\" placeholder=\"Username\" required autofocus>\n      <label for=\"inputPassword\" class=\"sr-only\">Password</label>\n      <input type=\"password\" id=\"inputPassword\" class=\"form-control\" name=\"password\" placeholder=\"Password\" required>\n      <div class=\"checkbox mb-3\">\n        <label>\n          <input type=\"checkbox\" value=\"remember-me\"> Remember me\n        </label>\n      </div>\n      <button class=\"btn btn-lg btn-primary btn-block\" type=\"submit\">Login</button>\n      <p class=\"mt-5 mb-3 text-muted\">&copy; <script>document.write(new Date().getFullYear());</script> Inari Amertron Berhad</p>\n    </form>\n  </body>\n</html>","output":"str","x":330,"y":240,"wires":[["9d0fc3ce.ac8af"]]},{"id":"d5793e1e.c48be","type":"function","z":"6ddaac4.fd62654","name":"select-query","func":"//Read username and password\n//var username = {payload: (msg.payload.username)};\n//var password = {payload: (msg.payload.password)};\n\n//SELECT Query\nmsg.topic=\"SELECT COUNT(*) AS count FROM users WHERE name='\" + msg.payload.username + \"' AND user_name='\" + msg.payload.password + \"'\";\n\nreturn msg;","outputs":1,"noerr":0,"x":330,"y":300,"wires":[["3e1d510c.94da4e"]]},{"id":"3e1d510c.94da4e","type":"mysql","z":"6ddaac4.fd62654","mydb":"272ea16.4569d5e","name":"database","x":500,"y":300,"wires":[["f9338ee5.2e00e"]]},{"id":"f9338ee5.2e00e","type":"function","z":"6ddaac4.fd62654","name":"check","func":"var count = msg.payload[0].count;\n\nif (count > 0)\n{\n    msg.payload = \"Login successful, \";\n}\nelse\n{\n    msg.payload = \"Login failed, \";\n}\nreturn msg;","outputs":1,"noerr":0,"x":650,"y":300,"wires":[["7314ec56.e4aff4","3e1cc7b4.977c78"]]},{"id":"9d0fc3ce.ac8af","type":"http response","z":"6ddaac4.fd62654","name":"","statusCode":"","headers":{},"x":1070,"y":240,"wires":[]},{"id":"7314ec56.e4aff4","type":"debug","z":"6ddaac4.fd62654","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":300,"wires":[]},{"id":"925066a5.4d5a38","type":"http in","z":"6ddaac4.fd62654","name":"","url":"/login","method":"post","upload":false,"swaggerDoc":"","x":110,"y":300,"wires":[["d5793e1e.c48be"]]},{"id":"3e1cc7b4.977c78","type":"template","z":"6ddaac4.fd62654","name":"result-page","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"Result: {{payload}}","output":"str","x":850,"y":360,"wires":[["9d0fc3ce.ac8af"]]},{"id":"272ea16.4569d5e","type":"MySQLdatabase","z":"","host":"","port":"3306","db":"ram_test","tz":""}]

At this flow, I'm able to get the result but I don't want the same url display the result. How to make the result to be displayed in another URL with username(session)?

Experts, kindly come forward and help as this is not only for me. If this is done, we are able to simply develop any kind of web application with ease using Node-Red. Node-Red will be used as the most productive tool to develop web applications moving forward.

For those who are helping, kindly provide a demo application so that it would be the best reference for all of us. A standard web application with MySQL database connection will do.

I found a node called node-red-contrib-users which looked like could fix this issue i'm trying to solve too. I thought It could work cause it allows you to create the users and the node acts like a switch so it looked like fine. Although I'm still not able to find the way to configure the logout.

Hello mannirivera

Check this flow out:

I'm using this a bit adapted to my need with making an auto logout after 5 minutes in order to write a global variable to lock or unlock some switches or functionalities on my system.

As example restart raspi or nodered service:

This is unlocked:


And this is logged:


In another post I also posted some feature I was doing to hide buttons depending on the state of a global variable, as example if TV is on:


but if TV is off:


If you look at you will find also some post with documentation in order to show and hide tabs with control_ui node, that maybe is interesting also for you and I'm also using for some feature.


Thank you for the information David... the thing is that... this way to use it could work for your application but not so much for mine... due to the fact that yes it will provide some password security to the system. Although just one user can be logged at a time. That's the problem. In my app the users register information in the database, I wanted o limit the access to submit the form just to registered users. What I have done in the meanwhile is to set an extra field in which in order to submit information the users have to put their password and if not the information wont be added to the database.

you might have already solved this since it has been 21 days
but just in case you haven't, let me tell you that in the "ui_control"
node it is stated "or just the tab name". So just send a msg.payload = "Your_Tab_Name" .
I've been using it like this in every app.

Edit: 21 days since the last comment


Hello community,

I am trying all day to find an answer to the question above. I have made an /ui form with username and password fields an I am able to "login" by hiding the Login Form if the user enters the right credentials, and showing the Main Forms.

But this does not solve the problems mannirivera72 posed. If I login from my pc, upon visiting the /ui from my smartphone(or another pc), no login is required. No user sessions are used. And last but not least, logout can only be achieved again by ui_control, hiding the Main Forms and showing the Login Form.

Am I missing something here? Is there an obvious way to have User Sessions in Node-Red that I haven't stumbled upon yet?

Thank you for your time,

can you paste /ui login form...