Websocket after OAuth2 authentication

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

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

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

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

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 :grin: (that's a joke by the way!).

Sorry I can't be of more help.

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.

More info

There is a python script for gardena/husqvarna devices available, perhaps easier to implement.

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?

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

@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).

    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 :grin:
Thanks for your kind efforts, anyway!

Cheers, C.

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.

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.

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

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.

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 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 :wink:

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