[英]NodeJS and Socket.io: Authentication across multiple modules
经过几年的广泛休息之后,我最近又重新选择了NodeJS。 上一次,我从来没有真正理解过包括模块(依赖项)的正确方法,而现在我试图集成身份验证,我真的很受困扰。 就是说,下面的代码可以正常工作,但是我无法摆脱这样的感觉,即我正在使它变得比原来更难。
这个问题可能是不合时宜的问题,但是我正在寻找一个包含准则和/或组织NodeJS代码的最佳实践的清晰示例的答案。 当然,理想情况下,请使用我的套接字身份验证示例。
app.js的相关部分。 先运行。
var core = require('./core/core')();
app.set('orangeCore', core);
Core.js包含我的“ main”方法,主要对其他服务进行异步API调用。 想法是在这些服务加入时将这些服务的响应提交到我的(套接字)频道。
function core() {
var self = this;
init();
self.getOrangeDevices = getOrangeDevices;
self.bindSocket = bindSocket;
return self;
function init() {...
}
function bindSocket(socket) {
socket.on('hello', function (msg) {
console.log('ello! ' + msg);
})
socket.emit('important-stuff', {
importantData: fromSomewhereElseInsideCore
});
}
}
module.exports = core;
然后是用于处理JWT身份验证的模块。 我已经基于socketio-jwt中间件了。 我真正不喜欢的以及导致我麻烦的是(我确实在这里给我留下了很多误解的余地)是异步完成的auth方法。 由于在身份验证完成之前,经过身份验证的套接字不会“公开”,因此我不理解如何以一种很好的方式绑定到该套接字。 因此我使用了诺言...
var io;
var socketioJwt;
var Promise = require('bluebird');
function setup(server, app) {
return new Promise(function (resolve, reject) {
io = require('socket.io')(server);
socketioJwt = require("socketio-jwt");
io.on('connection', socketioJwt.authorize({
secret: app.get('superSecret'),
timeout: 15000
})).on('authenticated', function (socket) {
console.log('client authenticated');
resolve(socket);
});
});
}
module.exports = {
listen: function (server, app) {
return setup(server, app);
}
}
最后,启动服务器的www.js文件。
var server = http.createServer(app);
// Sockets.io
var io = require('../socket/socket-channels');
io.listen(server, app).then(function(authSocket){
require('../core/core')().bindSocket(authSocket);
}, function(err){
console.error(err);
});
我真的不确定这是否可行。 我还想知道,一旦应用程序增长,它将在未来发展的前景如何。 我也没有看到一种实现套接字的名称空间功能的好方法,而不必为此设置JWT。
尽管您的目标客户端平台尚不清楚,但也许您可以从这个小的库中受益,该库允许通过WebSocket连接的两个参与方使用promise进行通信。
以及在该层外部进行身份验证的位置。 我不知道它是否适合您实际使用,但也许可以给您一些启发。
这是github上的lib
这是一个小例子:
服务器:
var io = require('socket.io')(server);
var Hook = require('./Hook');
var hook = new Hook();
var validatedSockets = {};
io.on('connection', function (socket) {
// listen for messages
hook.attach(socket);
// avoid memory leak and security holes
socket.on('disconnect', function () {
delete validatedSockets[socket.id]
})
});
hook.onHello(function (message, socket) {
var token = message && message.token;
return loadClient(token)
.then(function (clientData) {
if (!clientData) {
throw {error: "You don't have access"}
}
// mark socket as validated
validatedSockets[socket.id] = clientData;
return {ok: 1}
})
});
hook.onHook(function (event, message, socket) {
if (!validatedSockets[socket.id]) {
throw {error: "You are not validated"}
}
// this will be added as an extra argument for every event
return validatedSockets[socket.id];
});
hook.on('myEvent', function (message, socket, clientData) {
// do something and return something/Promise
});
客户:
// assuming commonJS but it can also be used in the browser directly
var Hook = require('./Hook');
var hook = new Hook();
var socket = io.connect("http://myServer.com");
hook
.attach(socket)
.bindSocket(socket) // enables 'send(message, data)' instead of 'sendTo(socket, message, data)' and 'sendHello' instead of 'sendHelloTo'
.sendHello({token: '123456789abcdefg'})
.then(function (message) {
console.log("Successful hello", message);
hook
.send('myEvent', {payload: '123'})
.then(function (message) {
console.log("Successful hook", message);
})
.catch(function (err) {
console.log("failed hook", err);
});
})
.catch(function (err) {
if (err === hook.TIMEOUT) {
// timeout
}
else {
console.log("hello failed", err);
}
});
(作者是我自己)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.