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

Ziy*_*iyu 34 node.js socket.io jwt

我正在尝试在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
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?谢谢.

ymy*_*yzk 40

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

例如:

var socket = io("http://localhost", {
  extraHeaders: {
    Authorization: "Bearer authorization_token_here"
  }
});
Run Code Online (Sandbox Code Playgroud)

engine.io-client是socket.io-client的后端,于2015-11-28 引入了extraHeaders支持.

  • 虽然这似乎是一个很好的选择,但它在使用NodeJS客户端时有效,但在浏览器中却无效.它在阅读中说明了这一点,大概是上面bakavic回答中第一个链接的b/c(并非所有传输都允许设置自定义标题) (11认同)
  • 太棒了,你如何得到服务器端的标题呢? (4认同)
  • 不幸的是,extraHeaders 仅在轮询模式下可用,而在 websocket 模式下不可用...... (2认同)

Buf*_*Dev 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;
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 完美的。这非常有效,并且是迄今为止最新的答案。 (2认同)

bak*_*vic 13

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

facundoolano的这篇文章详细介绍了一种不需要将auth令牌放在查询字符串中的身份验证的解决方法.

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

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

  • Socket.io 握手(即使对于 WebSockets)从常规 REST 调用开始并进一步提升到 WebSocket 协议,因此答案似乎是错误的,另一方面,如果您使用的是 HTTP 请求标头,那么这应该可以正常工作...... (3认同)

ada*_*hts 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
}
Run Code Online (Sandbox Code Playgroud)

此文档页面提供了上述信息和更深入的解释。

  • `io.set('authorization')` 实际上在 1.0 中已被弃用:http://socket.io/docs/migration-from-0-9/ (2认同)