Cas*_*per 5 node.js express node-redis passport.js cookie-session
我已经设置了一个工作登录测试,如下所示:
var express = require('express');
var fs = require('fs');
var http = require('http');
var path = require('path');
var routes = require('./routes/index.coffee');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('./userdb.coffee');
var app = express();
var RedisStore = require('connect-redis')(express);
passport.use(new LocalStrategy(function(username, password, done) {
return User.findOne({
username: username
}, function(err, user) {
if (err) {
return done(null, false, message: error);
}
if (!user) {
return done(null, false, {
message: 'Unknown user'
});
}
if (!user.validPassword(password)) {
return done(null, false, {
message: 'Invalid password'
});
} else {
return done(null, user);
}
});
}));
passport.serializeUser(function(user, done) {
return done(null, user);
});
passport.deserializeUser(function(user, done) {
return done(null, user);
});
app.configure(function() {
app.set('port', process.env.PORT || 5003);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.enable('trust proxy');
app.use(express["static"](path.join(__dirname, 'public')));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('SOMESECRET'));
app.use(express.session({
cookie: {
maxAge: 10 * 60 * 1000
},
key: 'express.sid',
secret: 'SOMESECRET',
store: new RedisStore({
port: 6379,
host: 'localhost'
})
}));
app.use(passport.initialize());
app.use(passport.session());
return app.use(app.router);
});
var check_auth = function(req, res, next) {
if (req.isAuthenticated()) {
console.log(req.session.cookie.expires);
return next();
}
return res.redirect('/login');
};
app.get('/', check_auth, routes.index);
app.get('/login', routes.login);
app.get('/logout', routes.logout);
app.post('/authenticate', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login'
}));
app.listen(app.get('port'), '0.0.0.0');
Run Code Online (Sandbox Code Playgroud)
路由和用户逻辑被省略了,因为我认为它们与我的问题无关,但我很乐意在需要时分享它们(它们非常小,这只是为了获得一个小概念证明并运行) .
登录工作,阅读会话工作,基于会话值的渲染模板工作. 我的问题是maxAge/expires.我不确定问题出在哪里,但我会试着描述一下:
当我登录时,会话被保存passport.js
,正确存储在我的中RedisStore
,并且指向会话的cookie被返回到浏览器.在后续请求中,cookie已成功找到并指向我的正确会话SessionStore
.req.session.cookie
显示UPDATED expires
并在我的redis
服务器中,TTL重置为10分钟(600).
我的问题是,cookie在浏览器中保持相同的时间(Chrome,Windows和Mac).
所以我的问题是:如何进一步调试?作为req.session(通过更新express
,passport
以及connect-redis
内部/自动),我不知道问题出在哪里,我应该怎样解决这个问题是什么:饼干保持初始maxAges /到期.
任何提示,指示或想法都非常受欢迎.
Express-session支持滚动cookie到期日期.不幸的是,它最近才被记录在案.
使用"滚动"选项进行会话.这"强制在每个响应上设置cookie"并"重置过期日期".您希望将滚动设置为true.
还要注意"重新保存"选项.即使未经修改也会"强制会话保存......"您可能也希望将该选项设置为true.请注意,即使此选项的默认值为true,也应该显式设置该值.现在不推荐使用此选项的默认值,而不是显式设置它.
尝试类似的东西:
app.use( session( { secret: 'keyboard cat',
cookie: { maxAge: 60000 },
rolling: true,
resave: true,
saveUninitialized: false
}
)
);
Run Code Online (Sandbox Code Playgroud)
这是文档.查看"选项"和"options.resave":https://github.com/expressjs/session.
经过一番挖掘后发现 Express 不支持这种滚动,因此留给程序员来实现。
如果浏览器的到期日期可以可靠地读取express
,那么您只能在会话接近到期时才可以更改会话,这将有所帮助,但我将其用作解决方法(效率低下),直到我找到更聪明的方法:
check_auth = function(req, res, next) {
console.log(req.isAuthenticated());
if (req.isAuthenticated()) {
if (req.session.roll) {
req.session.roll = 0;
} else {
req.session.roll = 1;
}
return next();
}
return res.redirect('/login');
};
Run Code Online (Sandbox Code Playgroud)
可能有任何事情roll
,重点是会话被更改(在每个经过身份验证检查的请求*)。
*) 这也意味着它的效率极低,但现在就可以了。
一种替代方法是查找会话 ID 的 TTL。这必须以如下方式进行检查:if ttl < 10% * maxAge(由应用程序定义),因为 TTL 实际上会在每个请求上正确更新,只是没有发送 Set-Cookie。因此,假设用户停留在 maxAge 的 90% 以内,他的浏览器 cookie 最终将过期,因此即使这种方法也不够。不过,这可能是一个很好的中间立场。
我将不接受该问题,以鼓励其他人提出更好的解决方案。
归档时间: |
|
查看次数: |
5413 次 |
最近记录: |