Socket.io-client: Método de handshake incorreto (somente ao usar cabeçalhos extras!)

Criado em 23 jun. 2017  ·  13Comentários  ·  Fonte: socketio/socket.io-client

Você quer:

  • [x] relatar um bug
  • [] solicitar um recurso

Comportamento atual

Recebo um 400 com a mensagem {"code":2,"message":"Bad handshake method"} quando tento conectar meu servidor com um cabeçalho extra (funciona bem se eu não tentar adicioná-lo).

Etapas para reproduzir (se o comportamento atual for um bug)

Tento conectar meu servidor com a seguinte configuração:

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

Também notei que uma solicitação OPTIONS é feita quando adiciono este cabeçalho extra (em vez de GET quando eu não o adiciono)

Comportamento esperado

Uma solicitação get GET (para preservar os cookies) com os cabeçalhos extras que não interrompem o handshake.

Configurar

  • SO: Mac
  • navegador: Chrome 58
  • versão socket.io: 2.0.3

Comentários muito úteis

Oi! Acho que você tem que adicionar os cabeçalhos adequados no lado do servidor (parece que você está em uma situação CORS):

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();
  }
});

Eu adicionei um exemplo lá: https://github.com/darrachequesne/socket.io-fiddle/tree/extra-headers

Todos 13 comentários

Mesmo problema, aqui .. funciona totalmente com a versão nodejs do socket.io-client, embora não o navegador

  • SO: Win
  • navegador: Chrome 59
  • versão socket.io: 2.0.3

Oi! Acho que você tem que adicionar os cabeçalhos adequados no lado do servidor (parece que você está em uma situação CORS):

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();
  }
});

Eu adicionei um exemplo lá: https://github.com/darrachequesne/socket.io-fiddle/tree/extra-headers

@darrachequesne como especificar vários domínios de origem, as seguintes maneiras não estão funcionando:

  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 você não pode usar múltiplos domínios, você precisa ler a origem do cabeçalho do cliente e verificar novamente sua lista de permissões.

veja isso e isso no stackoveflow

@DaVincii i definido como nulo, mas é liberado para qualquer domínio.

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

Para uso de CORS
{
handlePreflightRequest: function (req, res) {
var headers = {
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Origin': req.headers.origin,
'Access-Control-Allow-Credentials': verdadeiro
};
res.writeHead (200, cabeçalhos);
reenviar();
}
}

Para uso de CORS
{
handlePreflightRequest: function (req, res) {
var headers = {
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Origin': req.headers.origin,
'Access-Control-Allow-Credentials': verdadeiro
};
res.writeHead (200, cabeçalhos);
reenviar();
}
}

'Access-Control-Allow-Origin': req.headers.origin
Isso salvou meu dia! Quando eu usei:
'Access-Control-Allow-Origin': ' ',Isso me daria o seguinte erro:"O valor do cabeçalho 'Access-Control-Allow-Origin' na resposta não deve ser o caractere curinga ' ' quando o modo de credenciais da solicitação é 'incluir'. O modo de credenciais das solicitações iniciadas pelo XMLHttpRequest é controlado pelo atributo withCredentials . "

Isso parece não funcionar mais com o socket.io mais recente. O texto datilografado não gosta disso. Como consertar?
image

Isso parece não funcionar mais com o socket.io mais recente. O texto datilografado não gosta disso. Como consertar?

@ supertiger1234 handlePreflightRequest tem uma interface diferente na versão mais recente

Screenshot 2020-07-20 at 20 16 00

Então, no seu caso, deveria ser:

...
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 tem uma interface diferente na versão mais recente

⚠️ Se você instalar o socket.io agora a partir do npm, você terá uma versão antiga, mas se você instalar tipificações (via @types), terá novas tipificações! O que pode ser muito enganador.

Como instalo o socket io mais recente?

Para referência futura: esse problema também ocorre ao usar um servidor pós-3.0 com um cliente pré-3.0. Isso pode ser causado por um cache mal configurado que faz com que os clientes usem uma versão mais antiga de socket.io.js .

Para futuros leitores, consulte:

Esta página foi útil?
0 / 5 - 0 avaliações