用户注销Express,Socket.io,PassportJS时设置新的会话ID

时间:2016-01-02 03:11:22

标签: node.js session express socket.io passport.js

我正在编写消息传递应用程序,而我正在使用Express,Socket.io,PassportJS。

目前,当用户连接时,会给他们一个会话ID。这与websocket共享。当通过websocket进行通信时,我使用socket.request.session来获取有关会话的PassportJS信息。从那里我反序列化用户,然后确保他们有权执行他们正在尝试的操作。

当用户注销时,如果他们尝试发送消息,我的应用程序崩溃是因为websocket仍然具有先前的会话ID,即使我将其销毁到服务器端。

我不明白如何在用户注销时为其提供新的会话ID,以免他们最终崩溃服务器。

server.js:

var sessionStore = new MongoDBStore({
    uri: settings.dbUri,
    collection: settings.sessionCollection
});
var sessionMiddleware = session({
    secret: settings.sessionSecret,
    saveUninitialized: false,
    resave: false,
    cookie: {
        maxAge: 1000 * 60 * 60 * 24 * 7 // 1 week 
    },
    store: sessionStore
});
app.use(sessionMiddleware);
app.use(passport.initialize());
app.use(passport.session());

io.use(function(socket, next) {
    sessionMiddleware(socket.request, {}, next);
});
io.use(function(socket, next) {
    passport.initialize();
    passport.session();
    next();
});
// Handle routing to applications
app.get('/', function(req, res) {
    res.sendFile('player.html', {root: __dirname + '/apps/player'});
});

function returnUserOrContinue (req, res, next) {
    console.log(req.isAuthenticated());
    if (req.isAuthenticated()) {
    var user = { user: {
        username: req.user.username
    }};
    res.json(user);
    } else {
    return next()
    }
}

// User API
app.post('/userApi/login',
     returnUserOrContinue,
     passport.authenticate('localSignUp'),
     function(req, res) {
         var user = { user: {
         username: req.user.username
         }};
         res.json(user);
     });

app.post('/userApi/logout', function(req, res) {
    if (req.isAuthenticated()) {
    req.session.destroy();
    }
    res.send(null);
});

function ifUserLoggedIn(sessionID, callback) {
    sessionStore.get(sessionID, function(err, session){
    if (session && session.passport.user) {
        passport.deserializeUser(session.passport.user, function(err, user) {
        callback(user);
        });
    }
    });
}
io.on('connection', function(socket) {
    console.log('new socket connection');

    // Admin land
    socket.emit('updateQueue');

    // User Land
    socket.on('syncVideo', function() {
    socket.emit('currentVideoChanged', videoQueue.getCurrentVideoInfo());
    });
    socket.on('sendMessage', function(messageInfo) {
    var sessionID = socket.request.sessionID;
    ifUserLoggedIn(sessionID, function(user) {
        socket.broadcast.emit('newMessage', messageInfo);
    });
    });
});

server.listen(listenPort, '0.0.0.0', function(){
    console.log('listening on *:', listenPort);
});

passport.js:

var LocalStrategy = require('passport-local').Strategy;
var userController = require('./models/user').controller;

module.exports = function(passport) {
    passport.serializeUser(function(user, callback) {
    callback(null, user.id);
    });
    passport.deserializeUser(function(id, callback) {
    userController.getUserById(id, callback);
    });
    passport.use('localSignUp', new LocalStrategy(
    function(username, password, next){
        userController.getUserByUsername(username, function(user) {
        if (!user) {
            var newUser = userController.addUser(username, password);
            return next(null, newUser);
        }
        if (!userController.validPassword(user, password)) {
            return next(null, null);
        }
        return next(null, user);
        });
    }
    ));
}

1 个答案:

答案 0 :(得分:1)

您可以在注销时调用req.sesion.regenerate()以生成具有新会话ID的新会话。

req.session.regenerate(function(err) {
  // will have a new session here if no error
  res.send(null);
});