使用 Socket.IO 进行授权和握手

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

我想知道Socket.IO中授权和握手的主要功能是什么。我已经阅读了他们的 wiki 和 GitHub 上的授权指南,但我仍然不明白以下内容:

  1. Socket.io 中的授权是如何进行的?
  2. Socket.IO中的握手是什么?
  3. 我可以向
    handshakeData
    对象添加任何内容吗?

希望你能回答我的问题。谢谢。

javascript node.js sockets socket.io authorization
6个回答
75
投票

编辑: 在 Socket.IO 1.0 中,现在使用中间件。授权可以这样完成:

io.use(function(socket, next) {
  var handshake = socket.request;
  next();
});

如果您需要拒绝套接字,只需将错误对象传递给

next()
回调即可。命名空间也可以做同样的事情:

io.of('/namespace').use(function(socket, next) {
  var handshake = socket.request;
  next();
});

Socket.IO 中的授权是通过一个函数运行的,该函数由回调传递的布尔值决定。每次连接尝试握手时都会运行此函数,如下所示:

io.set('authorization', function (handshake, callback) {
  callback(null, true);
});

函数

callback()
接受两个参数。第一个是错误原因(如果有),第二个参数是决定客户端是否可以连接的布尔值。默认情况下没有授权,因此场景如上面的代码示例所示,其中正在连接的套接字允许通过,并带有
true

Socket.IO 中的握手与任何其他信息技术相关的握手类似。这是协商的过程,在 Socket.IO 的例子中,决定客户端是否可以连接,如果不能,则拒绝连接。握手通过 XHR 或 JSONP 请求启动,在未指定授权时不会执行太多操作,但对于在

handshake
数据对象中传递的数据很有帮助。

要回答你的最后一个问题,是的,你可以在

handshake
对象中添加任何内容。该对象是对
socket.handshake
对象的相同变量引用,它允许您执行以下操作:

io.set('authorization', function (handshake, callback) {
  handshake.foo = 'bar';
  callback(null, true);
});

io.sockets.on('connection', function(socket) {
  console.log(socket.handshake.foo); // bar
});

这非常有用,因为您可以存储基于套接字的属性。这样做的一个常见用途是在 Express 框架中,人们可以根据 Socket.IO 传递的 cookie 来识别会话 ID,然后可以识别匹配的会话。


13
投票

从 Socket.io 1.0 开始,虽然有向后兼容性,但建议使用“io.use()”来添加临时中间件,因此在节点服务器端:

io.use(function(socket, next){
  var joinServerParameters = JSON.parse(socket.handshake.query.joinServerParameters);
  if (joinServerParameters.token == "xxx" ){
    next();          
  } else {
    //next(new Error('Authentication error'));                  
  }
  return;       
});

在客户端,要将您自己的属性添加到握手中,它看起来像这样:

var joinServerParameters = { token: "xxx"   };    
var socket = io.connect('url' , {query: 'joinServerParameters=' + JSON.stringify(joinServerParameters)  });

2
投票

现在我正在使用这个简单的方法:

io.set('authorization', function (handshakeData, accept) {
  var domain = handshakeData.headers.referer.replace('http://','').replace('https://','').split(/[/?#]/)[0];
  if('myDomain.com'==domain)
    accept(null, true);
  else 
    return accept('Deny', false);
});

0
投票

在这种情况下

io.set('authorization', function (handshake, callback) {
    handshake.foo = 'bar';
    callback(null, true);
});

io.sockets.on('connection', function(socket) {
    console.log(socket.handshake.foo); // bar
});

socket.handshake.foo 会给出 undefined

我们需要在这里调用 socket.request.foo 以获得正确的值

有人误导了我们,因为 io auth 中间件需要 2 个参数,正确名称如下(请求,回调)而不是(握手,回调)PS:idk 可能以前的 io 版本有第二种情况:)

io.set('authorization', function (request, callback) {
    request.foo = 'bar';
    callback(null, true);
});

0
投票

如果您使用 JWT,在 socket.io 版本 4 中,您可以使用

handshake
对象来访问授权
Bearer token

io.use(async (socket, next) => {
    try {
        const accessToken = socket.handshake.headers.authorization.substring(7);
        const user = await fetchUser(socket);
        socket.user = user;
    } catch (e) {
        next(new Error("unknown user"));
    }
});

-1
投票

我知道为时已晚,但我想添加我发现有关使用 socket.io 进行握手授权的非常好的文章的信息。

socket.io授权

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