我已经设置了一个工作登录测试如下:
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');
省略了路线和用户逻辑,因为我认为它们与我的问题无关,但是如果需要,我会很乐意分享它们(它们很小,这只是为了获得较小的概念证明并运行)。
登录工作,阅读会话工作,基于会话值的渲染模板工作。我的问题是Maxage/Expires 。我不确定问题所在,但我会尝试描述它:
当我登录时,会话保存使用passport.js
,正确存储在我的RedisStore
中,并且指向会话的cookie将返回到浏览器。在随后的请求下,cookie已成功找到,并指向我的SessionStore
的正确会话。req.session.cookie
显示更新的expires
,在我的redis
服务器中,TTL重置为10分钟(600)。
我的问题是cookie在浏览器(Chrome,Windows和Mac)中保持同一期限。
所以我的问题是:如何进一步调试?随着Req.Sessess的更新(由express
,passport
和connect-redis
自动/自动),我想知道问题在哪里,以及我应该如何解决此问题: cookie仍处于最初的最大最大限度。
任何提示,指示或想法都会得到评价。
明确课程支持滚动饼干到期日期。不幸的是,它直到最近才记录下来。
为您的会话使用"滚动"选项。这"迫使一个曲奇设置在每个响应上",并"重置到期日期"。您想设置为true。
还要注意" Resave"选项。"即使没有修改也可以保存强制会话……"您可能也希望将该选项设置为真。请注意,即使此选项的默认值为真,您也应该明确设置该值。依靠此选项的默认值,而不是明确设置它。
尝试类似:
app.use( session( { secret: 'keyboard cat',
cookie: { maxAge: 60000 },
rolling: true,
resave: true,
saveUninitialized: false
}
)
);
这是文档。在"选项"one_answers" 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');
};
roll
可能是任何事物,重点是会话(在每个认证的请求*上)。
*)这也意味着它效率很低,但现在会做到。
一种选择是查找会话ID的ttl。这必须以这样的方式进行检查:如果ttl<10% * maxage(按应用程序定义),因为TTL实际上在每个请求上正确更新了,因此未发送Set-Cookie。因此,假设用户留在Maxage的90%之内,他的浏览器 - 奇语最终将过期,因此即使是该方法也不够。不过,这可能是一个很好的中间环。
我将不接受问题,以鼓励其他人使用更好的解决方案。
以防万一有人在Google Chrome中面对此问题,该解决方案非常容易:
app.use(cors({
allowedHeaders: ['Content-Type','Authorization'],
origin: '.dev.loc', <- your domain here, but it requires to have a dot infront
methods:['GET','POST','PUT','DELETE'],
preflightContinue: true
}));