繁体   English   中英

NodeJS和Socket.io:跨多个模块的身份验证

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM