在socket.io中发送自定义数据和handshakeData?

时间:2012-12-06 14:18:57

标签: node.js socket.io handshake

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

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

我认为最好将我的附加数据放在handshakeData的标题部分,所以任何想法我怎么能这样做? (如果可能的话,无需修改socket.io,但如果这是我可以忍受的唯一方式)

7 个答案:

答案 0 :(得分:135)

正如许多评论在下面指出的那样,Socket.IO API在1.0版本中发生了变化。现在应通过中间件功能进行身份验证,请参阅“身份验证差异”@ http://socket.io/docs/migrating-from-0-9/#authentication-differences。我将包括我的原始答案,因为旧的文档似乎已经消失了,所有人都坚持使用< 1.0。

1.0及更高版本:

客户端:

//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" });

服务器端:

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

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

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

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

在服务器上:

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

服务器上的输出看起来像是:

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

答案 1 :(得分:19)

现在已在v1.0.0中进行了更改。请参阅migration docs

基本上,

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

成为:

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

答案 2 :(得分:10)

对于socket.io v1.2.1,请使用:

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

答案 3 :(得分:7)

这是我的代码,用于向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);
}

答案 4 :(得分:1)

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

打印

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

如果有人知道如何通过握手从客户端获取数据到查询参数 ,请告诉我。

更新我后来用这种语法遇到了问题

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

是我目前正在使用的。

答案 5 :(得分:0)

我发现 .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
}

答案 6 :(得分:0)

旧线程,但是假设您将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()
  }
}

我现在正在将其用于项目,并且工作正常。