node.js 在 socket.io 中发送自定义数据和握手数据?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13745519/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:45:13  来源:igfitidea点击:

Send custom data along with handshakeData in socket.io?

node.jssocket.iohandshake

提问by Wingblade

So I have an application running node js with socket.io as a backend and normal javascript as frontend. My application has a login system which currently simply has the client send its login data as soon as it's connected.

所以我有一个运行 node js 的应用程序,socket.io 作为后端,普通 javascript 作为前端。我的应用程序有一个登录系统,目前它只是让客户端在连接后立即发送其登录数据。

Now I figured it would be much nicer to have the login data sent along with the handshakeData, so I can directly have the user logged in while connecting (instead of after establishing a connection) respectively refuse authorization when the login data is invalid.

现在我认为将登录数据与握手数据一起发送会更好,所以我可以在连接时(而不是建立连接后)直接让用户登录,当登录数据无效时分别拒绝授权。

I'm thinking it would be best to put my additional data in the header part of the handshakeData, so any ideas how I could do that? (Without having to modify socket.io if possible, but if it's the only way I can live with it)

我认为最好将我的附加数据放在握手数据的标题部分,那么我有什么想法可以做到这一点吗?(如果可能的话,不必修改 socket.io,但如果这是我可以忍受的唯一方法)

回答by Alex Wright

As a lot of comments have pointed out below the Socket.IO API changed in their 1.0release. Authentication should now be done via a middleware function, see 'Authentication differences' @ http://socket.io/docs/migrating-from-0-9/#authentication-differences. I'll include my orginal answer for anyone stuck on <1.0 as the old docs seem to be gone.

正如下面的许多评论指出的那样,Socket.IO API 在它们的1.0版本中发生了变化。现在应该通过中间件功能完成身份验证,请参阅“身份验证差异”@ http://socket.io/docs/migrating-from-0-9/#authentication-differences。由于旧文档似乎已经消失,我将包括我对 <1.0 上的任何人的原始答案。

1.0 and later:

1.0 及更高版本:

Client Side:

客户端:

//The query member of the options object is passed to the server on connection and parsed as a CGI style Querystring.
var socket = io("http://127.0.0.1:3000/", { query: "foo=bar" });

Server Side:

服务器端:

io.use(function(socket, next){
    console.log("Query: ", socket.handshake.query);
    // return the result of next() to accept the connection.
    if (socket.handshake.query.foo == "bar") {
        return next();
    }
    // call next() with an Error if you need to reject the connection.
    next(new Error('Authentication error'));
});

Pre 1.0

前 1.0

You can pass a query: param in the second argument to connect() on the client side which will be available on the server in the authorization method.

您可以在客户端将第二个参数中的 query: param 传递给 connect() ,该参数将在授权方法中在服务器上可用。

I've just been testing it. On the client I have:

我刚刚在测试它。在客户端我有:

var c = io.connect('http://127.0.0.1:3000/', { query: "foo=bar" });

On the server:

在服务器上:

io.set('authorization', function (handshakeData, cb) {
    console.log('Auth: ', handshakeData.query);
    cb(null, true);
});

The output on the server then looked like:

服务器上的输出如下所示:

:!node node_app/main.js
   info  - socket.io started
Auth:  { foo: 'bar', t: '1355859917678' }

回答by slupek2013

This has now been changed in v1.0.0. See the migration docs

这已经在 v1.0.0 中改变了。查看迁移文档

basically,

基本上,

io.set('authorization', function (handshakeData, callback) {
  // make sure the handshake data looks good
  callback(null, true); // error first, 'authorized' boolean second 
});

becomes :

变成:

  io.use(function(socket, next) {
  var handshakeData = socket.request;
  // make sure the handshake data looks good as before
  // if error do this:
    // next(new Error('not authorized');
  // else just call next
  next();
});

回答by zaynetro

For socket.io v1.2.1 use this:

对于 socket.io v1.2.1 使用这个:

io.use(function (socket, next) {
  var handshake = socket.handshake;
  console.log(handshake.query);
  next();
});

回答by user2969994

This my code for sending query data to nodejs and server.io server client.

这是我将查询数据发送到 nodejs 和 server.io 服务器客户端的代码。

var socket = io.connect(window.location.origin, { query: 'loggeduser=user1' });

io.sockets.on('connection', function (socket) {
    var endp = socket.manager.handshaken[socket.id].address;
    console.log("query... " + socket.manager.handshaken[socket.id].query.user);
}

回答by Harry Moreno

Perhaps the api has changed but I did the following to get extra info to the server.

也许 api 已更改,但我执行以下操作以向服务器获取额外信息。

// client
io.connect('localhost:8080', { query: 'foo=bar', extra: 'extra'});

// server
io.use(function(sock, next) {
  var handshakeData = sock.request;
  console.log('_query:', handshakeData._query);
  console.log('extra:', handshakeData.extra);
  next();
});

prints

印刷

_query: { foo: 'bar',
  EIO: '3',
  transport: 'polling',
  t: '1424932455409-0' }
extra: undefined

If anyone knows how to get data from a client to the server through the handshake that is not in the query paramslet me know please.

如果有人知道如何通过不在查询参数中的握手数据从客户端获取到服务器请告诉我。

UpdateI ran into issues later with this syntax

更新我后来遇到了这个语法的问题

io.connect('localhost:8080?foo=bar');

is what I'm currently using.

是我目前正在使用的。

回答by KM3

Old thread but assuming you store your jwt token/session id in session cookies (standard stuff) this gets passed to the server by default anyway when doing handshake (socket.io-client) I've noticed. Is there anything wrong with just getting the auth information for the handshake (via middleware or on.connection) via cookie? eg.

旧线程,但假设您将 jwt 令牌/会话 ID 存储在会话 cookie(标准内容)中,这在进行握手(socket.io-client)时默认情况下会传递给服务器,我注意到了。仅通过 cookie 获取握手的身份验证信息(通过中间件或 on.connection)有什么问题吗?例如。

io.on('connection', function(socket) {
  // assuming base64url token
  const cookieStr = socket.handshake.headers.cookie
  const matchRes =
    cookieStr == null
      ? false
      : cookieStr.match(/my-auth-token=([a-zA-Z0-9_.-]+)/)
  if (matchRes) {
    // verify your jwt...
    if ( tokenIsGood(matchRes[1]) {
      // handle authenticated new socket
    } else {
      socket.emit('AUTH_ERR_LOGOUT')
      socket.disconnect()
    }
  } else {
    socket.emit('AUTH_ERR_LOGOUT')
    socket.disconnect()
  }
}

I'm using this now for a project and it's working fine.

我现在在一个项目中使用它,它运行良好。

回答by user3678015

I found a little problem to see the .loggeduser

我发现了一个小问题,看.loggeduser

io.sockets.on('connection', function (socket) {
    var endp = socket.manager.handshaken[socket.id].address;
    console.log("query... " + socket.manager.handshaken[socket.id].query.loggeduser);
                                                                         // ↑ here
}