# Websocket after OAuth2 authentication

**URL:** <https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177>\
**Category:** General\
**Created:** [7 March 2021 00:07 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177 "2021-03-07T00:07:11Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![chrimu](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@chrimu](https://discourse.nodered.org/u/chrimu)\
**Post date:** [7 March 2021 00:07 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/1 "2021-03-07T00:07:12Z")

</div>

Hi,  
For connecting to a Websocket to continually receive updates without being blocked for excessive HTTP connects - in my case by the Husqvarna/Gardena Smart API - I just connect, authenticate and retreive the Websocket URL. This URL is only valid for 10sec., for security reasons as stated in their documentation.

What, despite a lot of reading, I failed to achieve is to feed this URL in a websocket client to establish connection within these 10sec. and get the updates - in this case of my sensor, mower and irrigation. I can't believe that's so exotic, but I still don't come to grip with it.

Anyone out there to give me a push, please?  
Cheers, Christian

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [7 March 2021 14:35 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/2 "2021-03-07T14:35:33Z")

</div>

Not sure that you can do that as you need to pass the authentication headers/cookies to the websocket connection and, at a quick wiz through the code, I can't see any option that would allow it.

You may have to write some websocket code yourself by exposing the `ws` module to a global variable in settings.js and then consuming it in a function node. Or writing a custom node.

There are quite a few other custom nodes that seem to be doing something similar:

[Library - Node-RED](https://flows.nodered.org/search?term=websocket)

---

<div class="post-metadata">

**Author:** ![chrimu](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@chrimu](https://discourse.nodered.org/u/chrimu)\
**Post date:** [7 March 2021 16:49 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/3 "2021-03-07T16:49:48Z")

</div>

Solution #2, writing a custom node, is surely beyond my competence...

Do you think you could maybe take me through solution #1?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [7 March 2021 16:53 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/4 "2021-03-07T16:53:19Z")

</div>

Frankly #1 is no easier I'm afraid. And I haven't done it myself.

What I suggest is that you look at some of the code from a couple of contributed nodes that are doing something similar but for a different API. You may be able to get sufficient information - you might even be able to copy one of them and make changes to meet your own needs.

Of course, if you want to send me a devices that uses the Husqvarna/Gardena Smart API, I'd happily code up something 😁 (that's a joke by the way!).

Sorry I can't be of more help.

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [7 March 2021 18:43 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/5 "2021-03-07T18:43:37Z")

</div>

An oauth2 flow requires a user to click "allow" via a browser window somewhere in the flow, this needs to be done one time only. Initial authentication is only the first of many steps, the click cannot be done with http request nodes or curl.

See the typical flow according to the RFC guidelines.

 ![oauth2](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/2/e2d4d1a4b618690190b384e04a40875c414d31f9.png)

[More info](https://darutk.medium.com/diagrams-and-movies-of-all-the-oauth-2-0-flows-194f3c3ade85)

There is a [python script for gardena/husqvarna devices available](https://github.com/py-smart-gardena/py-smart-gardena), perhaps easier to implement.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [7 March 2021 22:41 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/6 "2021-03-07T22:41:47Z")

</div>

I think that the main point is that you need to be able to pass the resulting token header on to the websocket handshake. Really you need to capture the normal interaction so that you can see exactly what is passed and how the API handles things when the token expires.

Using authentication tokens with websockets is not easy since you can only pass the header on the initial handshake. After that all you get is the messages over the socket and maybe a cookie if you've allowed them.

I don't think you can pass custom headers to the websocket nodes?

---

<div class="post-metadata">

**Author:** ![chrimu](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@chrimu](https://discourse.nodered.org/u/chrimu)\
**Post date:** [7 March 2021 23:01 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/7 "2021-03-07T23:01:09Z")

</div>

C'mon @TotallyInformation I was already sticking the stamp on the pack... 🤥

@bakman2 Thank you. But in my understanding the authentication thing lies already behind me here. All I'm left to do is firing up a websocket with a long, complicated and ever changing path as sole security feature, which was provided as result of authentication (websocket\_url is known and saved in a global variable, but I'm still unable to implement the code below).

```auto
    client = Client()
    ws = websocket.WebSocketApp(
        websocket_url,
        on_message=client.on_message,
        on_error=client.on_error,
        on_close=client.on_close)
    ws.on_open = client.on_open
    ws.run_forever(ping_interval=150, ping_timeout=1)

```

But that's as far as my competency goes... I guess I have to wait for a able coder having his/her lawn growing higher 😁  
Thanks for your kind efforts, anyway!

Cheers, C.

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [7 March 2021 23:07 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/8 "2021-03-07T23:07:24Z")

</div>

> But in my understanding the authentication thing lies already behind me here.

I highly doubt that, oauth2 is a highly annoying protocol and is not easy to get working from a flow in node-red Reading your post, you are at step 6. Still in the REST area, no websockets here.

The code you posted is exactly what the websocket nodes do, that are already build in, look in the palette on the left.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [7 March 2021 23:14 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/9 "2021-03-07T23:14:24Z")

</div>

> [@chrimu](#):
>
> All I'm left to do is firing up a websocket with a long, complicated and ever changing path as sole security feature

Ah, a clue there - does the websocket url have the token in the url parameters? Again, you really need to capture the interaction - you can probably do that just with your browser using a login to the normal web page. Have a look at the network tab of the browser dev tools.

---

<div class="post-metadata">

**Author:** ![chrimu](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@chrimu](https://discourse.nodered.org/u/chrimu)\
**Post date:** [7 March 2021 23:17 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/10 "2021-03-07T23:17:29Z")

</div>

No, past the "8", and that's exactly my question:  
I'm signed up, have my authentication token and refresh token. I know my login, password, api key and api secret. I've asked and got my location-ID (ID of my garden); with that I've asked and got my 10 sec. websocket URL (a long and cryptic thing, but not containing the token).

But how do I now get the URL in the NR websocket client?

BTW: The browser api is different , I think, from the api under [Husqvarna Group Cloud - Developer Portal](https://developer.husqvarnagroup.cloud/apis/GARDENA+smart+system+API#/readme)

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [7 March 2021 23:20 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/11 "2021-03-07T23:20:42Z")

</div>

> [@chrimu](#):
>
> But how do I now get the URL in the NR websocket client?

That's what I said at the start - the websocket nodes don't support dynamic url's I don't believe. You will need to reference the ws node in the globals section of settings.js Then use `global.get` in a function node to get the reference to the library. Then you should be able to follow the instructions for the library to pass the URL to create a reference. With the reference, you can create a listener function.

---

<div class="post-metadata">

**Author:** ![chrimu](https://avatars.discourse-cdn.com/v4/letter/c/43a26b/32.png) [@chrimu](https://discourse.nodered.org/u/chrimu)\
**Post date:** [7 March 2021 23:39 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/12 "2021-03-07T23:39:18Z")

</div>

I fully believe you and thank you!  
And yes, I also have read that one can't submit websocket paths dynamically. - Which in my case is a bit sad.

But still I have no clue and comprehension how or where to include the ws node in the globals section of settings.js, and how to use `global.get` in a function node to get the reference to the library...

Up to now, I'm firing up the whole websocket python script of the [Husqvarna Group Cloud - Developer Portal](https://developer.husqvarnagroup.cloud/apis/GARDENA+smart+system+API#/readme) via an exec node, but that's calling a whole new authentication session and so troubeling my token management for the regular API requests.

So yes, I'll try to learn and understand your solution #1...  
...and/or wait for the lawn to overwhelm node-creation-insiders 😉

---

<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:** [6 May 2021 23:39 UTC](https://discourse.nodered.org/t/websocket-after-oauth2-authentication/42177/13 "2021-05-06T23:39:34Z")

</div>

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