2012-08-15 35 views
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');已运行。Socket.io.js - 授权后拒绝连接仍然建立连接

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); 
    }); 

}); 

回答

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); 
       } 
      }); 
     } 
    }); 
});