Websocket with a dynamic Autharization header

It seams a bit odd, but reading other requests on this i still find it hard to believe that there is absolutely no way to dynamically change an authorization token for a WebSocket, just want to make sure is this right?

Ah, interesting! Never noticed that before. Clearly nobody else has ever bothered either.

Of course, the header is only available on the initial handshake for ws connections so an authorization header is of very limited use.

That screenshot is not of the built in node.

I think it is Steve:

Doh! I was looking at the out node (where I expected this to be!)

No worries, took me several attempts to find it. I guess neither of us really use that node. :rofl:

BTW, just seen my reply here:

Might give you a work-around.

if this limitation, not being able to dynamically set an authorization header like a token which by definition expires, then i am not surprised why not many use it.... seems useless for those cases where you need to authenticate to start a WebSocket connection... or am i missing something?

if the solution ends with "create your own node" :smiley: :smiley:

then.... i really question, why is it not a feature in the common / out of the box node.

You can always try a contrib node: Library - Node-RED

No you aren't missing anything. Raw websockets are of limited use in terms of security. You can authorise the initial handshake using a header (don't forget that you also need to use WSS: not WS: - e.g. you need a TLS secured connection) but then you cannot have a timed session. Which means that once connected, you cannot timeout the connection without some other mechanism on the server end and that generally means that the client simply gets cut off and then has to go through a reconnection handshake and authorisation all over again.

But see my possible workaround using Node-RED's pseudo environment variables.

Well, not many people use raw websockets directly, most people use an intermediary such as MQTT. Which is still lightweight but is far more feature rich. Where people do use them, they tend to be local and therefore unsecured or ...

Even big vendors struggle with this issue BTW - Microsoft Teams has an undocumented websocket feature and has to have a fixed authorization header. :smiley:

I was the one that PR'd the ability to include Headers for the UPGRADE operation during socket connections - as some OEM's require a token header of sorts for a successful connect.

As headers are only used once in the handshake, changing it after the connection will make no difference.

And FWIW: it can be "dynamic" - but is only used, when a connection is being made, not for current connections - as that is not possible in a web socket connection.

The value can be taken from an env variable

Not sure if any of this helps - but just to explain its existence :innocent:

That's not runtime dynamic tho.

I think the op wants the ability to connect and present a token that is potentially generated (or renewed) while flows are running.

Of course that would require the connection to be restarted.

Got it!

Taking the MQTT action:connect control message as an example
Adding the ability to have this supported in the WS Node I would think, would be a good addition.

And one that should address this scenario (allowing headers to be included in the connect action)

Exactly!

Thanks @Steve-Mcl for taking the words out of my mouth about $env variables not being the solution.

And thanks @marcus-j-davies for listening :slight_smile:

While i have your ‘ears’ it would be great to have the ability to read flow / global variables as typically tokens are stored there as opposed to $env variables and/or alternatively being able to pass the Authorization header in the msg itself when a ‘connect’ is initiated.

Have a great weekend!!!

1 Like

I think using flow variables at least, will see some non compatible approaches.
A Configuration Node, doesn't have access to anything in the flow (I cant answer for globals).

As the web socket connection itself sits 'outside' the gears of the flow - it can't see anything inside of them - unless passed a message indirectly via a Node subscribed to that Config Node.

I would like to see something that MQTT has, but extending to the Web Socket Node.
That allows to inject a new connection, but adding some toppings to support headers

This would address the need, and add some much needed control over the web socket node

/* msg */
{
  action: 'connect',
  webSocket: {
    url: 'ws://x.x.x.x',
    subProtocol: 'FooBar',
    mode: 'entire_message',
    headers: {
      token: 'xxxxxx',
      'user-agent':'BarFoo'
    }
  }
}

Just needs someone to PR it :wink:

Not sure why you chose ‘token’ to be a static attribute for the header….

In the cases am working with, the attribute is ‘Authorization’ and the value of the attribute is ‘Bearer xxxxxxxxx’.

In summary much like how an http node works.

Sorry - was just using token as an example

the token in my example is the header name
The headers in my example - are whatever is required at the other end.

headers: {
   Authorization: 'Bearer xxxxxxxxx’,
   'User-Agent': 'BarFoo',
   Accept: 'xxxxx',
   Anything: 'Really, that is required by your target server'
}

The headers names you put, don't need to follow any rule, whatever is required.