[javascript] HTTP headers in Websockets client API

Looks like it's easy to add custom HTTP headers to your websocket client with any HTTP header client which supports this, but I can't find how to do it with the JSON API.

Yet, it seems that there should be support these headers in the spec.

Anyone has a clue on how to achieve it?

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

Specifically, I need to be able to send an HTTP Authorization header.

This question is related to javascript http header websocket

The answer is


HTTP Authorization header problem can be addressed with the following:

var ws = new WebSocket("ws://username:[email protected]/service");

Then, a proper Basic Authorization HTTP header will be set with the provided username and password. If you need Basic Authorization, then you're all set.


I want to use Bearer however, and I resorted to the following trick: I connect to the server as follows:

var ws = new WebSocket("ws://[email protected]/service");

And when my code at the server side receives Basic Authorization header with non-empty username and empty password, then it interprets the username as a token.


Sending Authorization header is not possible.

Attaching a token query parameter is an option. However, in some circumstances, it may be undesirable to send your main login token in plain text as a query parameter because it is more opaque than using a header and will end up being logged whoknowswhere. If this raises security concerns for you, an alternative is to use a secondary JWT token just for the web socket stuff.

Create a REST endpoint for generating this JWT, which can of course only be accessed by users authenticated with your primary login token (transmitted via header). The web socket JWT can be configured differently than your login token, e.g. with a shorter timeout, so it's safer to send around as query param of your upgrade request.

Create a separate JwtAuthHandler for the same route you register the SockJS eventbusHandler on. Make sure your auth handler is registered first, so you can check the web socket token against your database (the JWT should be somehow linked to your user in the backend).


You can pass the headers as a key-value in the third parameter (options) inside an object. Example with Authorization token. Left the protocol (second parameter) as null


ws = new WebSocket(‘ws://localhost’, null, { headers: { Authorization: token }})

Edit: Seems that this approach only works with nodejs library not with standard browser implementation. Leaving it because it might be useful to some people.


You can not send custom header when you want to establish WebSockets connection using JavaScript WebSockets API. You can use Subprotocols headers by using the second WebSocket class constructor:

var ws = new WebSocket("ws://example.com/service", "soap");

and then you can get the Subprotocols headers using Sec-WebSocket-Protocol key on the server.

There is also a limitation, your Subprotocols headers values can not contain a comma (,) !


You cannot add headers but, if you just need to pass values to the server at the moment of the connection, you can specify a query string part on the url:

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

That URL is valid but - of course - you'll need to modify your server code to parse it.


Totally hacked it like this, thanks to kanaka's answer.

Client:

var ws = new WebSocket(
    'ws://localhost:8080/connect/' + this.state.room.id, 
    store('token') || cookie('token') 
);

Server (using Koa2 in this example, but should be similar wherever):

var url = ctx.websocket.upgradeReq.url; // can use to get url/query params
var authToken = ctx.websocket.upgradeReq.headers['sec-websocket-protocol'];
// Can then decode the auth token and do any session/user stuff...

More of an alternate solution, but all modern browsers send the domain cookies along with the connection, so using:

var authToken = 'R3YKZFKBVi';

document.cookie = 'X-Authorization=' + authToken + '; path=/';

var ws = new WebSocket(
    'wss://localhost:9000/wss/'
);

End up with the request connection headers:

Cookie: X-Authorization=R3YKZFKBVi

Technically, you will be sending these headers through the connect function before the protocol upgrade phase. This worked for me in a nodejs project:

var WebSocketClient = require('websocket').client;
var ws = new WebSocketClient();
ws.connect(url, '', headers);

In my situation (Azure Time Series Insights wss://)

Using the ReconnectingWebsocket wrapper and was able to achieve adding headers with a simple solution:

socket.onopen = function(e) {
    socket.send(payload);
};

Where payload in this case is:

{
  "headers": {
    "Authorization": "Bearer TOKEN",
    "x-ms-client-request-id": "CLIENT_ID"
}, 
"content": {
  "searchSpan": {
    "from": "UTCDATETIME",
    "to": "UTCDATETIME"
  },
"top": {
  "sort": [
    {
      "input": {"builtInProperty": "$ts"},
      "order": "Asc"
    }], 
"count": 1000
}}}

My case:

  • I want to connect to a production WS server a www.mycompany.com/api/ws...
  • using real credentials (a session cookie)...
  • from a local page (localhost:8000).

Setting document.cookie = "sessionid=foobar;path=/" won't help as domains don't match.

The solution:

Add 127.0.0.1 wsdev.company.com to /etc/hosts.

This way your browser will use cookies from mycompany.com when connecting to www.mycompany.com/api/ws as you are connecting from a valid subdomain wsdev.company.com.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to http

Access blocked by CORS policy: Response to preflight request doesn't pass access control check Axios Delete request with body and headers? Read response headers from API response - Angular 5 + TypeScript Android 8: Cleartext HTTP traffic not permitted Angular 4 HttpClient Query Parameters Load json from local file with http.get() in angular 2 Angular 2: How to access an HTTP response body? What is HTTP "Host" header? Golang read request body Angular 2 - Checking for server errors from subscribe No 'Access-Control-Allow-Origin' header in Angular 2 app How to add header row to a pandas DataFrame How can I make sticky headers in RecyclerView? (Without external lib) Adding header to all request with Retrofit 2 Python Pandas Replacing Header with Top Row Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers Pythonically add header to a csv file fatal error C1010 - "stdafx.h" in Visual Studio how can this be corrected? correct PHP headers for pdf file download How to fix a header on scroll

Examples related to websocket

Failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED WebSockets and Apache proxy : how to configure mod_proxy_wstunnel? javax.websocket client simple example getting the reason why websockets closed with close code 1006 Websocket onerror - how to read error description? WebRTC vs Websockets: If WebRTC can do Video, Audio, and Data, why do I need Websockets? How to make cross domain request How to use Tomcat 8 in Eclipse? Setting up a websocket on Apache? Differences between TCP sockets and web sockets, one more time