Using Node-RED to log in to Hubitat with security enabled [SOLVED]

I had originally posted under the Node-RED nodes for Hubitat thread but did not want to hijack that, So far, I have been able to figure out how to get to the Hubitat login page and get a responseCookie (using GET as method) and then use the original cookie (set it in the http request header), but I cannot get to login via the http request node.

When I look at the curl script that works, it appears that the it is using POST (not GET).


However, if I change the method of the http request node to "POST", I get a return Status Code of 500 (and no responseCookie in the return). I have tried setting the username/password in the node itself as well as as an input from a function node.

If I remove security from the hub, it works perfectly :anguished: Any tips would be greatly appreciated.

I finally figured out how to do this and download a backup from Hubitat, so I thought I would share the steps in Node-RED.

Node-RED components:

  1. Standard nodes - http request node, function node, change node, file node
  2. Extra - node-red-contrib-moment (used for formatting date to append to file name)

Hubitat Config:

  1. Security enabled (username/password).

Basic Approach:

  1. Use request node to get a session from the Hubitat server
  2. Use the responseCookie in the request header
  3. Use http request node to go to the login page. Set the username, password as FORM DATA (not basic authentication) and use POST method (not GET)
  4. Set the cookies again in the response header and set the URL in the http request node to download the backup.
  5. Save the output using the file node

Flow:

Step 1: This node is used to get a formatted date string which is used as part of the backup file name

Step 2: Sets the components of the full file name that is used by the file node in Step 9 (this can be skipped if you want to hard code the file name in the file node).


Step 3: This function node sets the full file path to msg.filename (this is required if the file name (with full path) is not specified in the file node.

Function node - Set Full File Path

msg.filename = msg.filePath+msg.backupDate+msg.fileSuffix;
return msg;

Step 4: This uses the http request node with the IP of the Hubitat login page to get the session cookies


Step 5: This function node sets the request headers (cookies, content-type) and the data for the Hubitat login form

Function node - SetRequestHeaders

var cookies = msg.responseCookies;
msg.headers = {
Cookie : "HUBSESSION=" + cookies.HUBSESSION.value,
'content-type':'application/x-www-form-urlencoded'};

//Hubitat login username and password for form data
var data = 'username=YOUR_USERNAME&password=YOUR_PASSWORD&submit=Login';
msg.payload = data;
return msg;

NOTE: If you have any special characters in your username and/or password, you may need to encode them (e.g. "!" = UTF %21 - I'm not sure if this is required or not, but when I captured the http data, it showed that special characters were encoded).

Step 6: This uses the http request node with the IP of the Hubitat login page using the POST method to log into Hubitat


Step 7: This function node again sets the cookies for the http request header

Function Node - Set Cookies

var cookies = msg.responseCookies;
//Set session cookies for the request header
msg.headers = {
Cookie : "HUBSESSION=" + cookies.HUBSESSION.value};
return msg;

Step 8: The http request node downloads the backup (not the "latest" backup as shown on the Hubitat Backup and Restore page, but it is the same as clicking the "Download" button on this page.

URL is http://YOUR_HUB_IP/hub/backupDB?fileName=latest
Step 9: The file node saves the downloaded file with the name/file path set in msg.filename earlier. If you want to save the file with the same name each time, you can just put in the file name and path here and skip Steps 1-3


I'm sure there are easier ways (I've been using the curl script from @aaiyar (?) and a combination of MacOS Automator and Calendar app on the Mac to automate the process.) However, I think this makes it more platform agnostic.

Since the flows have IP addresses, username, password in them, I have not posted the flows. I hope the detailed instructions help.

Let me know if this helps and if there are ways to improve this. Thanks

6 Likes

This is awesome! Thanks for writing this up!

1 Like

Thank you so much, I have been looking to do this for sometime now, just never got around to it. I wanted to be able to backup NR, Hubitat, and Pi-Hole all to google drive preferably.

  1. I think I have a solution for NR by creating a project and just posting to GitHub after any changes.
  2. Your guide above would solve the backup issue with Hubitat
  3. Pi-Hole I am still researching, but you have any ideas I would be all ears.

Do you know by chance how to, or even if its possible to, upload to google drive, or really any cloud server from NR?

I haven't done anything like that but you may want to check out node-red-contrib-google-storage (node) - Node-RED.

Yeah I saw that, but it seems to access the Google Cloud, which is their enterprise cloud solution, versus the consumer facing Google Drive.

2 Likes

My curl version works great so I am not going to switch now, but I am impressed that you figured it out.

I am blown away however at what a phenomenal write up you gave to allow others to both use your flow and know how it works.

:clap: :clap: :clap:well done :clap: :clap: :clap:

2 Likes

A couple of tweaks to (hopefully) improve things:

  1. Moved the login process to a sub-flow to make it easier to reuse
  2. Added a Change Node for username and password instead of hardcoding it in the function node.

Hubitat Login subflow:

Username/Password:
Added this prior to the original Step 4 - special characters are handled so there is no need to "encode" them,

Modified Step 5 function node:

Updated Function node

var cookies = msg.responseCookies;
msg.headers = {
Cookie : "HUBSESSION=" + cookies.HUBSESSION.value,
'content-type':'application/x-www-form-urlencoded'};

//Hubitat login username and password for form data
var data = 'username='+msg.username+'&password='+msg.password+'&submit=Login';
msg.payload = data;
return msg;

Examples using the login subflow:

HTTP Request node config for reboot:

4 Likes

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.