2016-02-04 52 views
0

我用快递4,Socket.IO 1.x和什么都是最新的护照是。我可以登录并保持登录状态,只要我在每次加载120秒(会话生命期)刷新我的屏幕。我有socket.io运行“ping/pong”,并且当服务器收到pong时,会话的到期更新并因此仍然有效。如果我在最后一次加载120秒后刷新屏幕,req.isAuthenticated()会返回false并将我踢出登录。如何让我自己用socket.io登录?Passport和Socket.IO - 保持使用Socket.IO登录?

这里是一些相关的代码:

var sessionMiddleware = session({ 
    store   : new RedisStore({}), // XXX redis server config 
    secret   : 'Some Key!', 
    cookie   : {maxAge: 120000}, 
    resave   : true, 
    saveUninitialized: true 
}); 

app.use(cookieParser()); // read cookies (needed for auth) 
app.use(bodyParser.urlencoded({extended: true})); 
app.use(sessionMiddleware); 
app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(express.static('public')); 
app.use(flash()); 


io.use(function(socket, next) 
{ 
    sessionMiddleware(socket.request, {}, next); 
    //sessionMiddleware(socket.request, socket.request.res, next); 
}); 

/** 
* Keeping the session alive through socket.io 
* Ping and Pong are reserved events on the client - so it's Ding and Dong for us! 
*/ 
function sendHeartbeat() 
{ 
    setTimeout(sendHeartbeat, 8000); 
    io.emit('ding', {beat: 1}); 
} 

app.get('/', function (req, res) 
{ 
    console.log('--------'); 
    console.log('From Get'); 
    console.log(req.session); 
    console.log('--------'); 
    if(!req.isAuthenticated()) 
    { 
     res.redirect('/login'); 
     return; 
    } 

    res.render('index', {sessionid: req.sessionID}); 
}); 

passport.use(new LocalStrategy(function (username, password, done) 
    { 
     console.log(username); 
     console.log(password); 

     db.query('SELECT * FROM `agents` WHERE `username` = ?', [username], function (err, rows) 
     { 
      if(err) 
      { 
       console.log(err); 
       return done(err); 
      } 
      var ret = JSON.parse(JSON.stringify(rows)); 

      if(ret.length != 1) 
      { 
       return done(null, false, {message: 'Incorrect username and/or password'}); 
      } 

      if(!bcrypt.compareSync(password, ret[0].password)) 
      { 
       return done(null, false, {message: 'Incorrect username and/or password'}); 
      } 

      return done(null, ret[0]); 
     }); 
    } 
)); 

passport.serializeUser(function (user, done) 
{ 
    done(null, user.agent_id); 
}); 

passport.deserializeUser(function (agent_id, done) 
{ 
    // Should use agent_id here - it's possibly faster. 
    db.query('SELECT * FROM `agents` WHERE `agent_id` = ?', [agent_id], function (err, rows) 
    { 
     if(err) 
     { 
      console.log(err); 
      return done(err); 
     } 
     var ret = JSON.parse(JSON.stringify(rows)); 
     console.log(ret[0]); 
     done(null, ret[0]); 
    }); 
}); 

app.get('/login', function (req, res) 
{ 
    if(req.isAuthenticated()) 
    { 
     res.redirect('/'); 
     return; 
    } 

    res.render('login'); 
}); 

app.post('/login', passport.authenticate('local', { 
     successRedirect: '/', 
     failureRedirect: '/login', 
     failureFlash : true 
    }) 
); 

io.on('connection', function (socket) 
{ 
    console.log('--------'); 
    console.log('From IO'); 
    console.log(socket.request.session); 
    console.log('--------'); 
    console.log('A socket with sessionID ' + socket.request.sessionID + ' connected!'); 

    // Ping and Pong are reserved events on the client - so it's Ding and Dong for us! 
    socket.on('dong', function (data) 
    { 
     // Keep session alive 
     socket.request.session.touch().save(function(err) 
     { 
      if(err) 
      { 
       console.log('Could not touch and save the session'); 
       return; 
      } 

      console.log('GOT PONG'); 
     }); 
    }); 
}); 

setTimeout(sendHeartbeat, 8000); 
+0

我也试图让客户端做一个AJAX调用页面每次被ping的时间,但只住了认证〜390秒(我改变30秒坪)。 app.get( '/保活',函数(REQ,RES) { 如果(req.isAuthenticated()){ res.send( 'OK'); 回报; } res.send ('坏'); }); – EllisGL

回答

0

我想通了。我删除了会话的TTL/maxAge。当然,我想确保会话在发生断开连接时被破坏,但不会在刷新后破坏会话。其他问题我认为客户端会在310秒的空闲时间内断开连接,即使使用ping/pong方案也是如此。我已经删除了ping/ponging,并更新了客户端在断开连接时重新连接并更新了断开连接代码,以确定它是刷新/临时断开连接还是完全断开连接。下面是一些simpiflied代码:

Sever的:

io.on('connection', function (socket) 
{ 
    // Add the socket.id to our session. 
    socket.request.session.socketid = socket.id; 

    socket.request.session.save(function(err) 
    { 
     if(err) 
     { 
      console.log('ERR', err); 
     } 
    }); 

    socket.on('disconnect', function() 
    { 
     // Lets make sure that we do not kill off sessions for reloads or temp disconnect (network hickups) 
     setTimeout(function() 
     { 
      socket.request.session.reload(function(err) 
      { 
       if(err) 
       { 
        console.log('ERR: ', err); 
       } 

       if(socket.id == socket.request.session.socketid) 
       { 
        // Full disconnect - destroy the session! 
        socket.request.session.destroy(function(err) 
        { 
         if(err) 
         { 
          console.log('Could not destroy the session', err); 
         } 
        }); 
       } 
      }); 
     }, 5000); 
    }); 
}); 

客户:

socket.on('disconnect', function() 
{ 
    // Reconnect after disconnect 
    socket.socket.reconnect(); 
}); 

我希望这可以帮助别人。