0

我使用的是 express v3.0.0、sockek.io 和 redis。当未经授权的用户请求连接时,发生了一些奇怪的事情。该行console.log( 'Error!!!');已运行,连接应被下一行拒绝return accept(err, false);。但是,连接仍然建立,并且线路socket.log.info('A socket with sessionID', hs.sessionID, 'connected');运行。

io = socketIO.listen(server);
io.configure(function () {
    io.set('authorization', function (data, accept) {
        // check if there's a cookie header
        if (data.headers.cookie) {
            data.cookie = parseSignedCookies(cookie.parse(decodeURIComponent(data.headers.cookie)), 'secret');
            data.sessionID = data.cookie['connect.sid'];
            // save the session store to the data object 
            // (as required by the Session constructor)
            data.sessionStore = sessionStore;
            sessionStore.get(data.sessionID, function (err, session) {
                if (session) {
                    req = {
                        sessionStore: sessionStore
                        , sessionID: data.sessionID
                    };
                    session = new express.session.Session(req, session);
                }
                if (err || !session) {
                    console.log( 'Error!!!');
                    return accept(err, false);
                } else {
                    // create a session object, passing data as request and our
                    // just acquired session data
                    data.session = new Session(data, session);
                    return accept(null, true);
                }
            });
        } else {
            // if there isn't, turn down the connection with a message
            // and leave the function.
            return accept('No cookie transmitted', false);
        }
        // accept the incoming connection
        accept(null, true);
    });
});

io.sockets.on('connection', function (socket) {
    var hs = socket.handshake;
    socket.log.info('A socket with sessionID', hs.sessionID, 'connected');
    // setup an inteval that will keep our session fresh
    var intervalID = setInterval(function () {
        // reload the session (just in case something changed,
        // we don't want to override anything, but the age)
        // reloading will also ensure we keep an up2date copy
        // of the session with our connection.
        hs.session.reload( function () { 
            // "touch" it (resetting maxAge and lastAccess)
            // and save it back again.
            hs.session.touch().save();
        });
    }, 60 * 1000);
    socket.on('disconnect', function () {
        socket.log.info('A socket with sessionID', hs.sessionID, 'disconnected');
        // clear the socket interval to stop refreshing the session
        clearInterval(intervalID);
    });

});
4

2 回答 2

2

问题出在您的授权方法的最后一行:

// accept the incoming connection
accept(null, true);

因为

sessionStore.get(data.sessionID, function (err, session) {

异步工作。您不得直接从授权函数中返回任何值,而只能从 sessionStore.get 回调函数返回。

完整的代码应该是:

io = socketIO.listen(server);
io.configure(function () {
    io.set('authorization', function (data, accept) {
        // check if there's a cookie header
        if (data.headers.cookie) {
            data.cookie = parseSignedCookies(cookie.parse(decodeURIComponent(data.headers.cookie)), 'secret');
            data.sessionID = data.cookie['connect.sid'];
            // save the session store to the data object 
            // (as required by the Session constructor)
            data.sessionStore = sessionStore;
            sessionStore.get(data.sessionID, function (err, session) {
                if (session) {
                    req = {
                        sessionStore: sessionStore
                        , sessionID: data.sessionID
                    };
                    session = new express.session.Session(req, session);
                }
                if (err || !session) {
                    console.log( 'Error!!!');
                    return accept(err, false);
                } else {
                    // create a session object, passing data as request and our
                    // just acquired session data
                    data.session = new Session(data, session);
                    return accept(null, true);
                }
            });
        }
    });
});
于 2012-08-17T13:31:37.857 回答
1

根据最新版本的 Socke.io,不推荐使用 io.set('authorization')。

相反,使用中间件。

我的项目中的代码片段如下:

io.use(SocketAuthRules.ensureUser)

In SocketAuthRules module, I have a function

function ensureUser (socket, next){
if(user!==null) { next() } else { next(new Error('not authorized')); } }

于 2020-10-17T01:08:16.777 回答