8

I'm trying to establish connection (client side) with Web Socket which requires Basic Access Authentication. From documentation I know that I should use username and password with base64 encryption. It's node.js application so I decide to use npm package SockJS-client. It seems to be good solution because:

Under the hood SockJS tries to use native WebSockets first. If that fails it can use a variety of browser-specific transport protocols and presents them through WebSocket-like abstractions.

But I have no clue how to establish connection using Basic Access Authentication. I have tried solution from here, but this one

var ws = new WebSocket("ws://username:password@example.com/service");

does not work, I got an error like:

SyntaxError: The URL's scheme must be either 'http:' or 'https:'. 'ws:' is not allowed.

When I'm trying with http/https I got:

Error: InvalidStateError: The connection has not been established yet

When I'm trying to call

sock.send('test');

Another solutions like that below is impossible to implement because I have no access to server side of Web Socket.

var ws = new WebSocket("ws://example.com/service?key1=value1&key2=value2");

I have no idea how to correctly establish authenticated connection with Web Socket, if you know any solutions let me know.

Bear
  • 1,017
  • 1
  • 10
  • 23

1 Answers1

16

Solution was pretty simple, but I think it is worth to place it here for next generations.

Finally, I implemented it by ws, you can find it here. First of all, I added header with field Authorization which contains encoded token. Another thing was a flag perMessageDeflate set to false.

The client will only use the extension if it is supported and enabled on the server.

That's how code looks like, works perfectly fine for me:

const WebSocket = require('ws');

const webSocket = new WebSocket(url, {
  perMessageDeflate: false,
  headers: {
    Authorization: `Basic ${encodedToken}`,
  },
});

webSocket.on('open', function open() {
  console.log('Connection has been established.');
});

I hope it will save you a lot of time.

Bear
  • 1,017
  • 1
  • 10
  • 23
  • 1
    subprotocol object is not invalid – Adi Prasetyo Feb 10 '22 at 16:05
  • Can you explain why did you need to disable compression for Basic Auth? How they are connected? – Sergey Jun 22 '22 at 09:33
  • 5
    Just FYI for anyone else coming across this, it no longer works. You cannot pass additional headers in the websocket request, because it's not actually HTTP. The initial handshake looks like HTTP (so that HTTP requests can be handled on the same port number) but the spec specifically says it's not HTTP, so there's no way to add extra headers (and websocket servers won't see them anyway as they discard the HTTP-compatible initial request). If you want to add auth to your websocket, you have to do it by sending messages over the socket itself. – Malvineous Jun 24 '22 at 03:14