跳到主要内容

简要分析socketio-auth

· 阅读需 7 分钟

看到不少noder在问socket.io如何控制权限这类问题,想到去年在echojs还是HackerNews上看到的socketio-auth模块,还是一定程度上解决这类问题的,尽管它的实现相当简单,但至少提供了一个思路。

socketio-auth是啥

也不详细介绍了,原文在这里《socket.io认证模块socketio-auth》

大致验证过程

1.为socket.io挂上模块

var io = require('socket.io').listen(app);

require('socketio-auth')(io, {
authenticate: authenticate,
postAuthenticate: postAuthenticate,
timeout: 1000
});

参数

  • authenticate 验证用户身份,比如在这里查询数据库,对比用户信息,成功后标记,然后调用下面的postAuthenticate函数
  • postAuthenticate 在验证成功后的处理,你可以做一些你爱做的事,比如买衣服什么的:)
  • timeout 超时时间,等待用户验证的时间毫秒数,超过这个时间就会强制断开了

在这个过程干了这么几件事:

这里主要是注册事件做准备工作。

2.客户端连接并进行验证

客户端在连接后,emit一个authentication事件并附带验证信息。 这时就会进入到验证流程里了,首先将信息传入authenticate方法里进行诸如查DB的验证过程。

// 验证
config.authenticate(data, function(err, success) {
if (success) {
debug('Authenticated socket %s', socket.id);
socket.auth = true;

...
} else if (err) {
...
} else {
...
}

});

// 验证的实现
function authenticate(data, callback) {
var username = data.username;
var password = data.password;

db.findUser('User', {username:username}, function(err, user) {
if (err || !user) return callback(new Error("User not found"));
return callback(null, user.password == password);
}
}

回调时看是否成功,成功就可以对连接进程标记了(稍后就不会被强制断开)。

成功时会调用postAuthenticate函数,比如将user信息绑定到连接或者其他的什么,总之,这个不是必须的。

3.返回状态给客户端

成功

socket.emit('authenticated', success);

失败

//error
socket.emit('unauthorized', {message: err.message}, function() {
socket.disconnect();
});

//fail
socket.emit('unauthorized', {message: 'Authentication failure'}, function() {
socket.disconnect();
});

后续任由客户端发挥了。

4.服务端还有一件小事要完成

那就是在timeout时间过后判断是否已验证,否则强制断开连接。

setTimeout(function() {
// If the socket didn't authenticate after connection, disconnect it
if (!socket.auth) {
debug('Disconnecting socket %s', socket.id);
socket.disconnect('unauthorized');
}
}, timeout);

完....

https://github.com/invisiblejs/socketio-auth

追加

@Pana 分享了另外两个也一并列出,有待研究 socketio-jwt session.socket.io