Socket.io-client: Bad handshake method (only when using extra headers!)

Created on 23 Jun 2017  ·  13Comments  ·  Source: socketio/socket.io-client

You want to:

  • [x] report a bug
  • [ ] request a feature

Current behaviour

I get a 400 with the message {"code":2,"message":"Bad handshake method"} when trying to connect my server with an extra header (works fine if i don't try to add it).

Steps to reproduce (if the current behaviour is a bug)

I try to connect my server with the following configuration:

  const options = {
    transportOptions: {
      polling: {
        extraHeaders: {
          Authorization: "Bearer test"
        }
      }
    }
  };

I also noticed that an OPTIONS request is made when i add this extra header (instead of a GET when i don't add it)

Expected behaviour

A get GET request (to preserve cookies) with the extra headers that don't break the handshake.

Setup

  • OS: Mac
  • browser: Chrome 58
  • socket.io version: 2.0.3

Most helpful comment

Hi! I think you have to add the proper headers on the server-side (it seems you're in a CORS situation):

const io = require('socket.io')(3000, {
  handlePreflightRequest: function (req, res) {
    var headers = {
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      'Access-Control-Allow-Origin': 'http://localhost:3001',
      'Access-Control-Allow-Credentials': true
    };
    res.writeHead(200, headers);
    res.end();
  }
});

I added an example there: https://github.com/darrachequesne/socket.io-fiddle/tree/extra-headers

All 13 comments

Same Issue, here.. totally works with the nodejs version of socket.io-client though not the browser

  • OS: Win
  • browser: Chrome 59
  • socket.io version: 2.0.3

Hi! I think you have to add the proper headers on the server-side (it seems you're in a CORS situation):

const io = require('socket.io')(3000, {
  handlePreflightRequest: function (req, res) {
    var headers = {
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      'Access-Control-Allow-Origin': 'http://localhost:3001',
      'Access-Control-Allow-Credentials': true
    };
    res.writeHead(200, headers);
    res.end();
  }
});

I added an example there: https://github.com/darrachequesne/socket.io-fiddle/tree/extra-headers

@darrachequesne how to specify multiple domains for origin, following ways are not working:

  1. 'Access-Control-Allow-Origin': 'http://localhost:3001, http://localhost:3002'
  2. 'Access-Control-Allow-Origin': ['http://localhost:3001, http://localhost:3002']
  3. 'Access-Control-Allow-Origin': 'http://localhost:3001 http://localhost:3002'

@DaVincii you cannot use multiple domains, you need to read the client header origin and check agains your whitelist.

see this and this on stackoveflow

@DaVincii i defined as null, but gets freed to any domain.

const headers = {
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Origin': null,
'Access-Control-Allow-Credentials': true
};

For CORS Use
{
handlePreflightRequest: function (req, res) {
var headers = {
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Origin': req.headers.origin ,
'Access-Control-Allow-Credentials': true
};
res.writeHead(200, headers);
res.end();
}
}

For CORS Use
{
handlePreflightRequest: function (req, res) {
var headers = {
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Origin': req.headers.origin ,
'Access-Control-Allow-Credentials': true
};
res.writeHead(200, headers);
res.end();
}
}

'Access-Control-Allow-Origin': req.headers.origin
This just saved my day! When I used:
'Access-Control-Allow-Origin': '',
It would give me the following error:
"The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '
' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute."

This does not seem to work anymore with the latest socket.io. Typescript does not like it. Anyway to fix?
image

This does not seem to work anymore with the latest socket.io. Typescript does not like it. Anyway to fix?

@supertiger1234 handlePreflightRequest has a different interface in the latest version

Screenshot 2020-07-20 at 20 16 00

So in your case it should be:

...
handlePreflightRequest: function(server, req, res) {
  var headers = {
    "Access-Control-Allow-Headers": "Content-Type, Authorization",
    "Access-Control-Allow-Origin": config.allowedOrigins,
    "Access-Control-Allow-Credentials": true,
  };

  res.writeHead(200, headers);
  res.end();
...

@supertiger1234 handlePreflightRequest has a different interface in the latest version

⚠️ If you install socket.io right now from npm you will have an old version, but if you install typings (via @types) it will have new typings! Which can be super misleading.

How do I install the latest socket io?

For future reference: this issue also occurs when using a post-3.0 server with a pre-3.0 client. This may be caused by a misconfigured cache that makes the clients use an older version of socket.io.js .

For future readers, please see:

Was this page helpful?
0 / 5 - 0 ratings