Socket.io-client: extraHeader ignored in browser

Created on 27 Jun 2016  ·  11Comments  ·  Source: socketio/socket.io-client

This line, seems to detect if we are in a node.js environment:

https://github.com/socketio/socket.io-client/blob/13002fb444e587ccdf2aa84711c8f0890d47b5ad/socket.io.js#L2177

However, I am trying to set in the browser (Angular) :
extraHeaders : { Authorization : 'Bearer xxxx' }

for JWT authentication to my REST service, hapi-io, which supports token authentication for websockets.

How else can I set a header or accomplish the same thing?

If I comment code around 2177, it doesn't not send the header.

Thanks

Most helpful comment

@fullstackwebdev since 2.0.0, you can now provide an extraHeaders object:

const socket = io({
  transportOptions: {
    polling: {
      extraHeaders: {
        'x-clientid': 'abc'
      }
    }
  }
});

Added to the documentation here.

All 11 comments

Note for people who found this via google in the future:

As a work around for now, I am passing the token in the query ( io.connect(undefined, { query : "token="+auth.getToken()} );

Then, on my server which is Hapi, I use hapi-auth-jwt2 which has a authentication strategy for tokens that has query parameter /?token= built in and enabled by default. Only use it with SSL.

However I would like to use extraHeaders if possible. Thanks!

Thanks @fullstackwebdev. I'm having trouble to find the documentation of the options.

@fullstackwebdev I've been fighting with extraHeaders in an angular app all day. I too think extraHeaders during the initial handshake would be the best way.

I just successfully implemented this concept which seems like a more elegant solution than passing query parameters. I think it should be safe if you are using SSL/wss.

Basically, you let the socket connect, but then make the client pass their token in an 'authorize' message.
Something like this (server):

io.on('connection', function (socket) {
    socket.authorized = false;
    socket.emit('connected', {connected: true, authorized: false});
    setTimeout(function(){
        if(!socket.authorized) {
            socket.disconnect(true);
    }, 1000; //1 second to authorize or kill the socket
    socket.on('authorize', function(data) {
        //validate token, set socket.authorized = true, socket.username etc

and this (client):

var socket = io(host);
socket.on('connected' function (data) {
    console.log("connected but not authorized");
    socket.emit('authorize', {token: "oauth/JWT token goes here";
});
socket.on('authorized', function (data) {
    console.log("authorized");
});

They have a point. If I remember correctly since sending headers is not the in the official spec of Websocket is not something they want to support.

The way I fixed this in my case is by sending the value I want to send through a cookie. But query params works too.

So this is supported now?

So it seems like this was added to master. Does anyone know if other clients (android,ios) will implement this soon ?

@vitriol @gaastonsr this is related to https://github.com/socketio/engine.io-client/issues/554

@fullstackwebdev since 2.0.0, you can now provide an extraHeaders object:

const socket = io({
  transportOptions: {
    polling: {
      extraHeaders: {
        'x-clientid': 'abc'
      }
    }
  }
});

Added to the documentation here.

This issue should be reopened for the websocket transport.
In the socket.io API documentation you've placed a link to the WebSocket RFC, chapter 4, but if you keep reading in there you'll encounter this paragraph:

 12.  The request MAY include any other header fields, for example,
        cookies [RFC6265] and/or authentication-related header fields
        such as the |Authorization| header field [RFC2616], which are
        processed according to documents that define them.

So, there's no rule against setting other headers from the browser, when establishing WebSocket connections - quite the contrary. By coincidence or not, I landed here precisely because of an authentication problem.

The engine.io-client's documentation should be ammended, too.

I got it, you're missing a proper API in browser. Damn.

Was this page helpful?
0 / 5 - 0 ratings