Node.js 使所有单个用户无效';express.js中的会话
出于安全原因,我们希望能够使用户的所有活动会话无效,例如,如果用户更改了密码,或者只是希望能够强制注销其其他会话。我们正在使用Node.js、Express、Express会话和Redis会话存储。在我们的应用程序中,我们有(CoffeeScript): Redis存储通过将唯一会话id映射到会话中存储的任何数据来工作。例如:Node.js 使所有单个用户无效';express.js中的会话,node.js,session,express,Node.js,Session,Express,出于安全原因,我们希望能够使用户的所有活动会话无效,例如,如果用户更改了密码,或者只是希望能够强制注销其其他会话。我们正在使用Node.js、Express、Express会话和Redis会话存储。在我们的应用程序中,我们有(CoffeeScript): Redis存储通过将唯一会话id映射到会话中存储的任何数据来工作。例如: # In an HTTP request req.session.user = { _id: "user-id" } 在Redis中变成: > get "sess
# In an HTTP request
req.session.user = { _id: "user-id" }
在Redis中变成:
> get "sess:<session-id>"
'{ "user": { "_id": "user-id" } } '
>获取“sess:
“{”用户“:{”用户id“}”
我们需要的是一种跟踪与每个用户id对应的所有会话的方法,这样,如果我们想使用户的会话无效,就可以从Redis中删除这些会话。以下注意事项适用:
谢谢大家! 对于类似的情况,我所做的是使用自定义会话ID,该ID在密钥名中包含用户ID。也许现在有一种更简单的方法来实现这一点,但我基本上要做的是设置自定义会话id: main.js:
var uid = require('uid'),
redis = require('redis'),
session = require('express-session'),
RedisStore = require('connect-redis')(session),
Session = session.Session,
Cookie = session.Cookie;
var utils = require('./utils');
var COOKIE_SECRET = 'somethingrandom',
COOKIE_KEY = 'mycustomsession';
var redisClient = redis.createClient(),
redisStore = new RedisStore({
client: redisClient,
ttl: 24 * 60 * 60, // 1 day session expiration
prefix: 'sess:'
});
// ... then inside the login route after user was successfully authenticated ...
req.sessionStore = redisStore;
req.sessionID = 'sess:' + user.id + ':' + uid(24);
req.session = new Session(req);
req.session.cookie = new Cookie({});
req.session.user = user;
utils.createSession(req, res, COOKIE_KEY, COOKIE_SECRET);
utils.js:
var onHeaders = require('on-headers'),
signature = require('cookie-signature');
exports.createSession = function(req, res, name, secret) {
var trustProxy = true;
// ripped from express-session
onHeaders(res, function() {
if (!req.session)
return;
var cookie = req.session.cookie
, proto = (req.headers['x-forwarded-proto'] || '').split(',')[0].toLowerCase().trim()
, tls = req.connection.encrypted || (trustProxy && 'https' == proto);
// only send secure cookies via https
if (cookie.secure && !tls)
return;
var val = 's:' + signature.sign(req.sessionID, secret);
res.cookie(name, val, cookie.data);
});
// proxy end() to commit the session
var end = res.end;
res.end = function(data, encoding) {
res.end = end;
if (!req.session) return res.end(data, encoding);
req.session.resetMaxAge();
req.session.save(function(err) {
if (err) console.error(err.stack);
res.end(data, encoding);
});
};
};
谢谢然后如何使用户的所有会话过期?我们在Redis中存储了大量其他数据,使用
键或扫描进行完全扫描实际上是不可行的。我想,我们需要能够进行某种直接查找。我使用带有模式的SCAN
,没有任何问题。但是,您可以使用单独的数据库进行会话和SCAN
,或者使redis键不唯一(键入前缀+用户id)以及包含该用户会话JSON数组的值?谢谢,我认为单独的数据库和SCAN
的组合在这种情况下确实可以工作。谢谢你的回答!
var onHeaders = require('on-headers'),
signature = require('cookie-signature');
exports.createSession = function(req, res, name, secret) {
var trustProxy = true;
// ripped from express-session
onHeaders(res, function() {
if (!req.session)
return;
var cookie = req.session.cookie
, proto = (req.headers['x-forwarded-proto'] || '').split(',')[0].toLowerCase().trim()
, tls = req.connection.encrypted || (trustProxy && 'https' == proto);
// only send secure cookies via https
if (cookie.secure && !tls)
return;
var val = 's:' + signature.sign(req.sessionID, secret);
res.cookie(name, val, cookie.data);
});
// proxy end() to commit the session
var end = res.end;
res.end = function(data, encoding) {
res.end = end;
if (!req.session) return res.end(data, encoding);
req.session.resetMaxAge();
req.session.save(function(err) {
if (err) console.error(err.stack);
res.end(data, encoding);
});
};
};