redis 清除单个用户的所有会话

nfs0ujit  于 2023-04-10  发布在  Redis
关注(0)|答案(2)|浏览(159)

在我的网站上,我想一个组织的管理员能够重置用户密码的表单.理想情况下,当这重置,我想从我的RedisStore中清除该用户的所有可识别会话,其中包含express和passport的会话数据.有人想出了一种方法来做到这一点吗?

qf9go6mv

qf9go6mv1#

你可以快速地从Redis中通过键找到项目,但是因为识别正确会话所需的数据是在值中,所以你需要遍历所有键,看看哪些属于有问题的用户。
您可以在用户登录时按用户名将会话ID存储到集合中,然后当您需要删除会话时,您只需从列表中获取密钥并删除它们,然后删除列表。

var client = redis.createClient();
// Add the session ID to a set (if not there already)
passport.use(new LocalStrategy({passReqToCallback: true}, function (req, username, password, cb) {
  // Do normal login stuff first. 
  // RedisStore adds 'sess:' to session ID when making it a key
  client.sadd("sessions:" + user.username, "sess:" + req.session.id);
  cb(null, user);
}));

然后删除会话:

var deleteSessions = function(username, cb) {
  client.smembers("sessions:" + username, function(err, sessionIds) {
    if (sessionIds.length === 0) return cb();
    // Delete all sessions
    client.del.apply(client, sessionIds);
    // Delete the set containing now deleted session IDs
    client.del("sessions:" + username);
    cb();
  });
};
ulmd4ohb

ulmd4ohb2#

@vesse的解决方案是解决这个问题的好方法,但是,在他的情况下,只有在调用passport.authenticate()(通常只在'/login'路由上使用)时,而不是在每次登录时,新的sessionId才会被添加到Set中。
如果您在多个路由上登录用户,在多个地方使用req.login(),您应该将新的sessionId添加到serializeUser中的Set,它会在您调用passport.authenticate()req.login()时被调用。

// passing in req: https://github.com/jwalton/passport-api-docs#passportserializeuserfnuser-done--fnreq-user-done
passport.serializeUser(function (req, user, done) {
    // Track user's open sessionIds, by saving them under userId-key as a Set
    client.sAdd('sessions:' + user._id, 'sess:' + req.session.id);

    done(null, user._id);
});

相关问题