# Node red to OMNI REST API token request

**URL:** <https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918>\
**Category:** General\
**Tags:** http-request, security\
**Created:** [29 October 2021 00:12 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918 "2021-10-29T00:12:27Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Logan](https://avatars.discourse-cdn.com/v4/letter/l/278dde/32.png) [@Logan](https://discourse.nodered.org/u/Logan)\
**Post date:** [29 October 2021 00:12 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/1 "2021-10-29T00:12:27Z")

</div>

Hi Everyone

New to the community and the node-red platform. Please excuse my unfamiliarity with adding information to posts, etc.

To the point of the post.. I have a Commercial controller that hosts a web server and is REST API capable.  
I am having issues with getting the token from the controller. My issue currently is the hashing of the "salt" and including the password.

I'm not sure how to achieve this. i have downloaded pallets that do the function of hashing and un-hashing, if that's what it is, and no success. The API information can be found [Here](https://documenter.getpostman.com/view/10295427/TWDdkuAe#e53bd2dc-86db-4ec8-ac18-10abb2a4c1a8) that uses postman (if you're familiar with it).

I have not included any flows currently but will get it together.  
Any help or insight would be greatly appreciated.

-Logan

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [29 October 2021 00:30 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/2 "2021-10-29T00:30:31Z")

</div>

Hello Logan and welcome to the Node-red Forum,

Were you able to make a succesful request to your BMS controller API using the Postman software ?

---

<div class="post-metadata">

**Author:** ![Logan](https://avatars.discourse-cdn.com/v4/letter/l/278dde/32.png) [@Logan](https://discourse.nodered.org/u/Logan)\
**Post date:** [29 October 2021 00:39 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/3 "2021-10-29T00:39:07Z")

</div>

Hi!

Thanks so much for the reply.

Yes. so the postman works perfectly without a hitch. Just cant get it to work via node red. My eventual objective is to add this to home assistant. but from my constant changing and testing, I'm having such a hard time. its not as simple as copy paste from the official documentation

Currently I can get a reply with the salt.  
The rest I cant figure out.

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [29 October 2021 00:45 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/4 "2021-10-29T00:45:46Z")

</div>

it seems that you need to do a series of http requests  
one to get the salt ---\> get token ---\> request actual data

Try to import this flow (Ctrl-I) , change the function node to the ip/username of your controller  
See if you get the salt in NR.

```auto
[{"id":"be4cb634d6fc8b19","type":"inject","z":"5847b7aa62131d37","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":350,"y":600,"wires":[["08068f0eee8663e5"]]},{"id":"08068f0eee8663e5","type":"function","z":"5847b7aa62131d37","name":"prepare req","func":"msg = {\n\n method: 'post',\n url: 'https://192.168.30.51/api/salt',\n headers: {\n 'Content-Type': 'application/json'\n },\n payload: JSON.stringify({ \"username\": \"Innotech\" })\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":600,"wires":[["de23c9b11c6a7aa8","578d3d4950128bc2"]]},{"id":"de23c9b11c6a7aa8","type":"http request","z":"5847b7aa62131d37","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":740,"y":600,"wires":[["8322c617ff387fcc"]]},{"id":"578d3d4950128bc2","type":"debug","z":"5847b7aa62131d37","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":540,"wires":[]},{"id":"8322c617ff387fcc","type":"debug","z":"5847b7aa62131d37","name":"salt","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":930,"y":600,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![Logan](https://avatars.discourse-cdn.com/v4/letter/l/278dde/32.png) [@Logan](https://discourse.nodered.org/u/Logan)\
**Post date:** [29 October 2021 01:01 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/5 "2021-10-29T01:01:02Z")

</div>

Thanks again.

So i pasted it in and got the following response:

```auto
uJXCKFT2M6JhVvi5tIAGwfSWZ4AXvK80a2t8Ararqps=

```

So it does work.

so where it gets complicated is the part where you need to get the encryption right.  
so in postman, it is the following code:

```auto
import sha256 from 'crypto-js/sha256'
import base64url from 'base64url'
import Base64 from 'crypto-js/enc-base64'
import Latin1 from 'crypto-js/enc-latin1'

export const hashCredentials = (credential, salt) => {
 const concats = credential + atob(salt)
 const notbase64 = sha256(Latin1.parse(concats))
 const hashedCredential = Base64.stringify(notbase64)
 return base64url.fromBase64(hashedCredential)
}

```

crypto-js is not in the node red library. this is where i hit a brick wall. Would you have any ideas?

-Logan

Edit:  
I have tried numerous pallets. the pallets either don't work or there are issues with errors.

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [29 October 2021 01:16 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/6 "2021-10-29T01:16:23Z")

</div>

> [@Logan](#):
>
> so where it gets complicated is the part where you need to get the encryption right

yea i was reading about it now.

Function nodes (in latest Node-red versions) have something called `functionExternalModules` that give you the ability to require external npm libraries like crypto-js etc  
you can read how to set that up in your NR `settings.js` file [here](https://nodered.org/docs/user-guide/writing-functions#using-the-functionexternalmodules-option)

Once you have that setup you set the modules in the **Setup tab** of a new Function node (after the salt http request)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/4/74a71587a431d8b0b1cb8ad36fd2027a64aadc29.png)

And in **On Message** Tab something like

```auto
let salt = msg.payload.client_salt;
let credential = "<your_credential>"

const concats = credential + atob(salt)
const notbase64 = sha256(Latin1.parse(concats))
const hashedCredential = Base64.stringify(notbase64)
let hashCredentials = base64url.fromBase64(hashedCredential)

node.warn({hashCredentials}) // log hashCredentials

```

Note: One issue i noticed is that Node.js doesnt support the atob() command .. not until version 16

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [29 October 2021 01:41 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/7 "2021-10-29T01:41:17Z")

</div>

**Example Flow using npm atob library :**

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/9/79c86b41c7aa7bd6a523fb8cd9531fb19f571a7f.png)

```auto
[{"id":"be4cb634d6fc8b19","type":"inject","z":"5847b7aa62131d37","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":220,"y":600,"wires":[["08068f0eee8663e5"]]},{"id":"08068f0eee8663e5","type":"function","z":"5847b7aa62131d37","name":"prepare req","func":"msg = {\n\n method: 'post',\n url: 'https://192.168.30.51/api/salt',\n headers: {\n 'Content-Type': 'application/json'\n },\n payload: JSON.stringify({ \"username\": \"Innotech\" })\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":600,"wires":[["de23c9b11c6a7aa8","578d3d4950128bc2"]]},{"id":"de23c9b11c6a7aa8","type":"http request","z":"5847b7aa62131d37","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":610,"y":600,"wires":[["8322c617ff387fcc","69fc0d787e6d1653"]]},{"id":"578d3d4950128bc2","type":"debug","z":"5847b7aa62131d37","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":530,"y":540,"wires":[]},{"id":"8322c617ff387fcc","type":"debug","z":"5847b7aa62131d37","name":"salt","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":730,"y":540,"wires":[]},{"id":"69fc0d787e6d1653","type":"function","z":"5847b7aa62131d37","name":"prepare req","func":"let salt = msg.payload.client_salt;\nlet credential = \"<your_cretential>\"\nlet username = \"<your_username>\"\n\nconst concats = credential + atob(salt)\nconst notbase64 = sha256(Latin1.parse(concats))\nconst hashedCredential = Base64.stringify(notbase64)\nlet hashCredentials = base64url.fromBase64(hashedCredential)\n\nnode.warn({hashCredentials}) // log hashCredentials\n\n\nlet data = `{\\r\\n \"username\": \"${username}\", \\r\\n \"password\": \"${hashCredentials}\" \\r\\n}`;\n\n msg = {\n method: 'post',\n url: 'https://192.168.30.51/api/token',\n headers: { \n 'Content-Type': 'application/json'\n },\n payload : data\n};\n\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"sha256","module":"crypto-js/sha256"},{"var":"base64url","module":"base64url"},{"var":"Base64","module":"crypto-js/enc-base64"},{"var":"Latin1","module":"crypto-js/enc-latin1"},{"var":"atob","module":"atob"}],"x":840,"y":600,"wires":[["12bf0194cfc78c44","a697a6653bd2cfee"]]},{"id":"f616a86568848154","type":"inject","z":"5847b7aa62131d37","name":"Test salt","props":[{"p":"payload.client_salt","v":"uJXCKFT2M6JhVvi5tIAGwfSWZ4AXvK80a2t8Ararqps=","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"str","x":680,"y":700,"wires":[["69fc0d787e6d1653"]]},{"id":"12bf0194cfc78c44","type":"debug","z":"5847b7aa62131d37","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":950,"y":540,"wires":[]},{"id":"a697a6653bd2cfee","type":"http request","z":"5847b7aa62131d37","name":"","method":"use","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":1050,"y":600,"wires":[["a94527145710a597"]]},{"id":"a94527145710a597","type":"debug","z":"5847b7aa62131d37","name":"token","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1210,"y":600,"wires":[]}]

```

> **[atob](https://www.npmjs.com/package/atob)**
>
> atob for Node.JS and Linux / Mac / Windows CLI (it's a one-liner)

---

<div class="post-metadata">

**Author:** ![Logan](https://avatars.discourse-cdn.com/v4/letter/l/278dde/32.png) [@Logan](https://discourse.nodered.org/u/Logan)\
**Post date:** [29 October 2021 02:25 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/8 "2021-10-29T02:25:47Z")

</div>

UnborN

You are a legend my friend. works without a hitch.

just for future reference, here is the response:

```auto
{"method":"post","url":"https://192.168.50.50/api/token","headers":{"set-cookie":["omni_session=AmVebQZiDGAELlJ2XDwGMVM1VGgCcV8gWjsJd1ckBWlXPFM8VQ0HO1Q2ACsAagQhBG8AZA9nBTkBdVI2VmRaZlRkXGcBOQUyVzUENQczVzICYl4zBjMMPgQwUmBcNwY3U2NUZwJgXzFabQk3V2MFOVcxUzFVYgdjVDcAKwBqBCEEbwBmD2UFOQF1Uj1Wd1oJVDFcNQFlBXJXNgR2B3NXIAI%2FXiQGbQxrBGdSP1wkBjFTPFRgAn1fYlpoCTxXeQU1V2NTfFVgB3BUaQB6AGsEYwRlAG0PdwV2ASRSMVZ1WglUMVw2AWQFblcnBCcHO1dxAj5eYwZmDGAEd1JiXGkGdFMlVHoCO18nWioJdFckBTpXfFN9VTUHO1QmAGEAJAQwBHsANA86BW4BeFInVm5aOFQ0XCMBZAVzVzwEdwdoV3cCd154BjAMNQQhUixcJAY7U3ZUaAJiX2BaZAkmVzsFYVcgUyZVDQczVDEAfQA4BCQEPAAjDywFIQFsUj1WPVpnVGZcYgE0BTRXZAQxBzBXNAIzXmwGJAxgBGxSP1wkBnVTdlQ3AiFfDFo6CWVXIwVhV3FTaVUhB2hUYgAzAHMEcARuACo%3D; path=/; httponly"],"access-control-allow-origin":"*","content-type":"application/json","access-control-allow-methods":"GET, POST, PUT, DELETE, OPTIONS","access-control-allow-headers":"Access-Control-Allow-Headers, Content-Type, Access-Control-Allow-Methods, Authorization, X-Requested-With","strict-transport-security":"max-age=63072000; includeSubDomains; preload","x-frame-options":"SAMEORIGIN","x-content-type-options":"nosniff","content-length":"638","connection":"close","date":"Fri, 29 Oct 2021 02:21:07 GMT","server":"lighttpd","x-node-red-request-node":"57426448"},"payload":{"token":{"token_type":"Bearer","access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ikk1QU9SaUp4ZnFLeDEyZlYrZ2M9In0.eyJpc3MiOjAsInN1YiI6Im1kZk1rdHk1b0dcL0RMYzZvN2xSbHJuNVd5QT09IiwiYXVkIjoiODdjZjg0NTQtYzkyZi00NjI0LTliM2ItM2UzNzdmZTc3NjNhIiwibmJmIjoxNjM1NDc0MDY3LCJpYXQiOjE2MzU0NzQwNjd9.cUMGDJlm9-34jO19w7Q0j3dTNTf2S1ttwKtwfITZVkHOyJrNoPly-GalKEdVAkZRxsJzT6_K0VW5tvyyVtZv6q5v4hD7n_po4s9DA1PCt-OI3VDv9_Jw-neAlRBd5AdhFq5jBXlXCfZze0jv9hE1SXeXE1vIsSOQcslzA6q4SQ1vl5kDv9ItfOQQMCv8UsAZ0btHUVvmzxwxZ7SCu6ON0xG8kuzdxIb0KvqjXChpG6SvVACQ11yA_zTPtyDcKSgqOA933KUstYlySvh21d5qulXyP3z1GEDRqv28fn5Rd7DMX3pMY0bCRz8IFzoQGCbBMPkcGhUKrqZtBHeHZEHp0A"}},"_msgid":"7c35dab03df7da60","statusCode":200,"responseUrl":"https://192.168.50.50/api/token","redirectList":[],"retry":0,"responseCookies":{"omni_session":{"path":"/","value":"AmVebQZiDGAELlJ2XDwGMVM1VGgCcV8gWjsJd1ckBWlXPFM8VQ0HO1Q2ACsAagQhBG8AZA9nBTkBdVI2VmRaZlRkXGcBOQUyVzUENQczVzICYl4zBjMMPgQwUmBcNwY3U2NUZwJgXzFabQk3V2MFOVcxUzFVYgdjVDcAKwBqBCEEbwBmD2UFOQF1Uj1Wd1oJVDFcNQFlBXJXNgR2B3NXIAI/XiQGbQxrBGdSP1wkBjFTPFRgAn1fYlpoCTxXeQU1V2NTfFVgB3BUaQB6AGsEYwRlAG0PdwV2ASRSMVZ1WglUMVw2AWQFblcnBCcHO1dxAj5eYwZmDGAEd1JiXGkGdFMlVHoCO18nWioJdFckBTpXfFN9VTUHO1QmAGEAJAQwBHsANA86BW4BeFInVm5aOFQ0XCMBZAVzVzwEdwdoV3cCd154BjAMNQQhUixcJAY7U3ZUaAJiX2BaZAkmVzsFYVcgUyZVDQczVDEAfQA4BCQEPAAjDywFIQFsUj1WPVpnVGZcYgE0BTRXZAQxBzBXNAIzXmwGJAxgBGxSP1wkBnVTdlQ3AiFfDFo6CWVXIwVhV3FTaVUhB2hUYgAzAHMEcARuACo="}}}

```

now just need to dabble with it and see what it can do.

Really, thankyou so much.

-Logan

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [29 October 2021 02:57 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/9 "2021-10-29T02:57:54Z")

</div>

Cool .. jeez its like getting authenticated for a nuclear power station 😉

the rest are more basic requests once you add the Bearer + token in the headers in a similar way in a preceding function.

If it helps you can set on your site the language to Nodejs-Axios , which is a library that most resembles the NR http request properties. except `data` which should be `payload`

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/3/630d557b8d70937f21efd1c72b938505913a2997.png)

---

<div class="post-metadata">

**Author:** ![Logan](https://avatars.discourse-cdn.com/v4/letter/l/278dde/32.png) [@Logan](https://discourse.nodered.org/u/Logan)\
**Post date:** [29 October 2021 03:00 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/10 "2021-10-29T03:00:48Z")

</div>

```auto
Cool .. jeez its like getting authenticated for a nuclear power station

```

I know right!  
the data is quite secure. only downside is the OMNI will not post. so polling only.. maby something to push up to RND?

i will look into Nodejs-Axios for sure.

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [29 October 2021 03:11 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/11 "2021-10-29T03:11:59Z")

</div>

> [@Logan](#):
>
> only downside is the OMNI will not post. so polling only

does it have something to do with the User group you used to authenticate ?

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/3/b34b3a7e7c108b1632b17edf1d5ec45f227a1358.png)

---

<div class="post-metadata">

**Author:** ![Logan](https://avatars.discourse-cdn.com/v4/letter/l/278dde/32.png) [@Logan](https://discourse.nodered.org/u/Logan)\
**Post date:** [29 October 2021 04:22 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/12 "2021-10-29T04:22:54Z")

</div>

No. So the access levels simply put restrictions on access.  
So, as a BMS controller, Innotech don't want people accessing back end settings and information. They are hidden.

Another example

Facilities manager will have access to setpoints. But staff can only view them.

Access levels are just restrictions.

So by post, I mean if you want to receive an update on an alarm for high temp, you can't. You need to setup something to poll for the information in the event the state changes.

---

<div class="post-metadata">

**Author:** ![UnborN](https://avatars.discourse-cdn.com/v4/letter/u/4491bb/32.png) [@UnborN](https://discourse.nodered.org/u/UnborN)\
**Post date:** [29 October 2021 12:06 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/13 "2021-10-29T12:06:39Z")

</div>

just polling. I understand the problem now.  
I guess you'll have to set an Inject node on Repeat interval, to poll the controller as often you see necessary (as far as the device can handle it) in order to get the alarms.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [12 November 2021 12:07 UTC](https://discourse.nodered.org/t/node-red-to-omni-rest-api-token-request/52918/14 "2021-11-12T12:07:07Z")

</div>

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