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 に答える