socket.io-client 在建立连接时如何设置请求头

问题描述 投票:0回答:9

我试图在socket.io客户端发出连接请求时设置一个http标头。有办法做到这一点吗?

这就是我正在做的:

// server side
var io = socketio(server);

io.use(function (socket, next) {
  // authorize using authorization header in socket.request.headers
});

// client side
var socket = io();  // i'm trying to set an authorization header in this http reqeust

有什么想法吗?谢谢。

node.js socket.io jwt
9个回答
75
投票

如果您使用的是socket.io-client >= 1.4,则可以使用

extraHeaders
选项。

例如:

var socket = io("http://localhost", {
  extraHeaders: {
    Authorization: "Bearer authorization_token_here"
  }
});

engine.io-client,是socket.io-client的后端,于2015-11-28

引入了
extraHeaders支持。


18
投票

有一种新方法可以做到这一点:https://socket.io/docs/v3/middlewares/。查看“发送凭据”部分。

// client
const socket = io(server, {
    transports: ['websocket', 'polling', 'flashsocket'],
    auth: {
        token: 'abc'
    }
});

// server
io.use((socket, next) => {
    const token = socket.handshake.auth.token;
    if (isValidJwt(token)){
        next();
    }else{
        next(new Error("Socket authentication error"));
    }
});

async function isValidJwt(token){
    jwt.verify(token, secrets.jwt, function(err, decoded) {
        if (err){
            console.log(err);
            return false;
        }else{
            //console.log(decoded);
            return true;
        }
    });
}

15
投票

似乎客户端不支持设置标头,因为并非所有传输都允许设置标头。

facundoolano 的这篇post详细介绍了一种身份验证解决方法,不需要将身份验证令牌放入查询字符串中。

他的解决方法模块可以在https://github.com/invisiblejs/socketio-auth找到。

让我想知道为什么在服务器端,socket.io 允许访问请求标头...


4
投票

以下信息自 socket.io 1.0 起已被弃用

授权有两种方法:全局或命名空间(想想路由)。全局方法是通过

io.set('authorization', function (handshakeData, callback)
配置调用在服务器上设置的。

handshakeData对象包含以下信息:

{
   headers: req.headers       // <Object> the headers of the request
 , time: (new Date) +''       // <String> date time of the connection
 , address: socket.address()  // <Object> remoteAddress and remotePort object
 , xdomain: !!headers.origin  // <Boolean> was it a cross domain request?
 , secure: socket.secure      // <Boolean> https connection
 , issued: +date              // <Number> EPOCH of when the handshake was created
 , url: request.url          // <String> the entrance path of the request
 , query: data.query          // <Object> the result of url.parse().query or a empty object
}

可以在此文档页面获取上述信息和更深入的解释。


3
投票

自版本 2.0.0 / 2017-01-22 起,engine.io-client 支持

[feature] Allow extraHeaders to be set for browser clients in XHR requests (#519)

然而,此时 socket.io-client 尚未更新以支持此功能,因此几天后可能会让这个传奇结束,直到那时使用以下说明:https://facundoolano.wordpress.com/2014/10 /11/socket-io-no-query-strings 的更好身份验证/


2
投票

“transportOptions”选项可用于在socket.io请求中发送额外的标头。我也在这里解释过:-

Node.js + Socket.io |在服务器上设置自定义标头


2
投票

由于某种原因,只有当套接字服务器也是socket.io时才会收到这些请求标头。 例如,如果我连接到 python Websockets 服务器,我就无法进行身份验证。

对我有用的唯一解决方案是使用不同的 WebSocket 客户端,例如,

ws
工作正常。

import WebSocket from 'ws';

const socket = new WebSocket('wss://example.com/path', {
      headers: {
            Authorization: 'token'
         },
 });


1
投票

简短回答:这是基于规范的 imposiburu...如果您只需要尽早传递信息...为什么不查询参数?

socket = io('localhost:5000', {
      path: '/mySocketPath',
      transports: ['websocket'],
      query: {
        token:'some-token-value'
      }
})

参见@satpal-07 https://github.com/socketio/socket.io-client/issues/1356#issuecomment-810023635


0
投票

如果您将令牌存储在 cookie 中,则只需提供

withCredentials: true,
选项即可。

© www.soinside.com 2019 - 2024. All rights reserved.