我正在使用Express 4,Socket.IO 1.x以及最新的Passport。我可以登录,并且只要我在每次加载120秒内刷新我的屏幕(会话的生命时间),就可以保持登录状态。我有socket.io运行“ping / pong”,当服务器收到一个pong时,会话的到期时间更新,因此仍然有效。如果我在最后一次加载120秒后刷新屏幕,req.isAuthenticated()会返回false并将我踢出登录。如何让我自己使用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 :(得分:0)
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();
});
我希望这有助于其他人。